/*
 * QQQ - Low-code Application Framework for Engineers.
 * Copyright (C) 2021-2022.  Kingsrook, LLC
 * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
 * contact@kingsrook.com
 * https://github.com/Kingsrook/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package com.kingsrook.qqq.backend.core.model.metadata.frontend;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.kingsrook.qqq.backend.core.model.actions.metadata.MetaDataOutput;
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppSection;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;


/*******************************************************************************
 * Version of QAppMetaData that's meant for transmitting to a frontend.
 *
 *******************************************************************************/
@JsonInclude(Include.NON_NULL)
public class QFrontendAppMetaData
{
   private String name;
   private String label;
   private String iconName;

   private List<String>             widgets  = new ArrayList<>();
   private List<AppTreeNode>        children = new ArrayList<>();
   private Map<String, AppTreeNode> childMap = new HashMap<>();

   private List<QAppSection> sections;



   /*******************************************************************************
    **
    *******************************************************************************/
   public QFrontendAppMetaData(QAppMetaData appMetaData, MetaDataOutput metaDataOutput)
   {
      this.name = appMetaData.getName();
      this.label = appMetaData.getLabel();

      if(appMetaData.getIcon() != null)
      {
         this.iconName = appMetaData.getIcon().getName();
      }

      List<String> filteredWidgets = CollectionUtils.nonNullList(appMetaData.getWidgets()).stream().filter(n -> metaDataOutput.getWidgets().containsKey(n)).toList();
      if(CollectionUtils.nullSafeHasContents(filteredWidgets))
      {
         this.widgets = filteredWidgets;
      }

      List<QAppSection> filteredSections = new ArrayList<>();
      for(QAppSection section : CollectionUtils.nonNullList(appMetaData.getSections()))
      {
         List<String> filteredTables    = CollectionUtils.nonNullList(section.getTables()).stream().filter(n -> metaDataOutput.getTables().containsKey(n)).toList();
         List<String> filteredProcesses = CollectionUtils.nonNullList(section.getProcesses()).stream().filter(n -> metaDataOutput.getProcesses().containsKey(n)).toList();
         List<String> filteredReports   = CollectionUtils.nonNullList(section.getReports()).stream().filter(n -> metaDataOutput.getReports().containsKey(n)).toList();
         if(!filteredTables.isEmpty() || !filteredProcesses.isEmpty() || !filteredReports.isEmpty())
         {
            QAppSection clonedSection = section.clone();
            clonedSection.setTables(filteredTables);
            clonedSection.setProcesses(filteredProcesses);
            clonedSection.setReports(filteredReports);
            filteredSections.add(clonedSection);
         }
      }

      if(CollectionUtils.nullSafeHasContents(filteredSections))
      {
         this.sections = filteredSections;
      }
   }



   /*******************************************************************************
    ** Getter for name
    **
    *******************************************************************************/
   public String getName()
   {
      return name;
   }



   /*******************************************************************************
    ** Getter for label
    **
    *******************************************************************************/
   public String getLabel()
   {
      return label;
   }



   /*******************************************************************************
    ** Getter for children
    **
    *******************************************************************************/
   public List<AppTreeNode> getChildren()
   {
      return children;
   }



   /*******************************************************************************
    ** Getter for childMap
    **
    *******************************************************************************/
   public Map<String, AppTreeNode> getChildMap()
   {
      return childMap;
   }



   /*******************************************************************************
    ** Getter for iconName
    **
    *******************************************************************************/
   public String getIconName()
   {
      return iconName;
   }



   /*******************************************************************************
    ** Setter for iconName
    **
    *******************************************************************************/
   public void setIconName(String iconName)
   {
      this.iconName = iconName;
   }



   /*******************************************************************************
    **
    *******************************************************************************/
   public void addChild(AppTreeNode childAppTreeNode)
   {
      if(children == null)
      {
         children = new ArrayList<>();
      }
      childMap.put(childAppTreeNode.getName(), childAppTreeNode);
      children.add(childAppTreeNode);
   }



   /*******************************************************************************
    ** Getter for widgets
    **
    *******************************************************************************/
   public List<String> getWidgets()
   {
      return widgets;
   }



   /*******************************************************************************
    ** Getter for sections
    **
    *******************************************************************************/
   public List<QAppSection> getSections()
   {
      return sections;
   }
}
