/*****************************************************************
 *   Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 ****************************************************************/

package org.apache.cayenne.modeler.editor.cgen;

import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.Component;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.prefs.Preferences;
import java.util.stream.Collectors;

import org.apache.cayenne.gen.CgenConfiguration;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.Embeddable;
import org.apache.cayenne.map.Entity;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.modeler.ProjectController;
import org.apache.cayenne.modeler.dialog.pref.GeneralPreferences;
import org.apache.cayenne.modeler.util.CayenneController;
import org.apache.cayenne.modeler.util.CellRenderers;
import org.apache.cayenne.modeler.util.ModelerUtil;
import org.apache.cayenne.validation.ValidationFailure;
import org.apache.cayenne.validation.ValidationResult;

/**
 * @since 4.1
 * A base superclass of a top controller for the code generator. Defines all common model
 * parts used in class generation.
 *
 */
public abstract class CodeGeneratorControllerBase extends CayenneController {

    public static final String SELECTED_PROPERTY = "selected";

    protected DataMap dataMap;
    protected ValidationResult validation;
    protected List<Object> classes;
    private Set<String> selectedEntities;
    private Set<String> selectedEmbeddables;
    private Set<String> isDataMapSelected;
    private Map<DataMap, Set<String>> selectedEntitiesForDataMap;
    private Map<DataMap, Set<String>> selectedEmbeddablesForDataMap;
    private Map<DataMap, Set<String>> selectedDataMaps;
    protected transient Object currentClass;
    protected ProjectController projectController;

    protected boolean initFromModel;

    public CodeGeneratorControllerBase(CayenneController parent, ProjectController projectController) {
        super(parent);
        this.projectController = projectController;
        this.classes = new ArrayList<>();
        this.selectedEntitiesForDataMap = new HashMap<>();
        this.selectedEmbeddablesForDataMap = new HashMap<>();
        this.selectedDataMaps = new HashMap<>();
        this.selectedEntities = new HashSet<>();
        this.selectedEmbeddables = new HashSet<>();
        this.isDataMapSelected = new HashSet<>();
    }

    public void startup(DataMap dataMap){
        initFromModel = true;
        this.dataMap = dataMap;
        prepareClasses(dataMap);
    }

    private void prepareClasses(DataMap dataMap) {
        classes.clear();
        this.classes.add(dataMap);
        this.classes.addAll(dataMap.getObjEntities());
        this.classes.addAll(dataMap.getEmbeddables());
        initCollectionsForSelection(dataMap);
    }

    private void initCollectionsForSelection(DataMap dataMap) {
        selectedEntities = selectedEntitiesForDataMap.compute(dataMap, (key,value) ->
                value == null ? new HashSet<>() : value);
        selectedEmbeddables = selectedEmbeddablesForDataMap.compute(dataMap, (key, value) ->
                value == null ? new HashSet<>() : value);
        isDataMapSelected = selectedDataMaps.compute(dataMap, (key, value) ->
                value == null ? new HashSet<>() : value);
    }

    /**
     * Creates a class generator for provided selections.
     */
    public CgenConfiguration createConfiguration() {
        DataMap map = projectController.getCurrentDataMap();
        CgenConfiguration cgenConfiguration = projectController.getApplication().getMetaData().get(map, CgenConfiguration.class);
        if(cgenConfiguration != null){
            addToSelectedEntities(cgenConfiguration.getEntities());
            addToSelectedEmbeddables(cgenConfiguration.getEmbeddables());
            cgenConfiguration.setForce(true);
            return cgenConfiguration;
        }

        cgenConfiguration = new CgenConfiguration(false);
        cgenConfiguration.setForce(true);
        cgenConfiguration.setDataMap(map);

        Path basePath = Paths.get(ModelerUtil.initOutputFolder());

        // no such folder
        if (!Files.exists(basePath)) {
            try {
                Files.createDirectories(basePath);
            } catch (IOException e) {
                JOptionPane.showMessageDialog(getView(), "Can't create directory. Select a different one.");
                return null;
            }
        }

        // not a directory
        if (!Files.isDirectory(basePath)) {
            JOptionPane.showMessageDialog(this.getView(), basePath + " is not a valid directory.");
            return null;
        }

        cgenConfiguration.setRootPath(basePath);
        Preferences preferences = application.getPreferencesNode(GeneralPreferences.class, "");
        if (preferences != null) {
            cgenConfiguration.setEncoding(preferences.get(GeneralPreferences.ENCODING_PREFERENCE, null));
        }

        addToSelectedEntities(map.getObjEntities()
                .stream()
                .map(Entity::getName)
                .collect(Collectors.toList()));
        addToSelectedEmbeddables(map.getEmbeddables()
                .stream()
                .map(Embeddable::getClassName)
                .collect(Collectors.toList()));
       getApplication().getMetaData().add(map, cgenConfiguration);
       projectController.setDirty(true);

        return cgenConfiguration;
    }

    public List<Object> getClasses() {
        return classes;
    }

    public abstract Component getView();

    public void validate(GeneratorController validator) {

        ValidationResult validationBuffer = new ValidationResult();

        if (validator != null) {
            for (Object classObj : classes) {
                if (classObj instanceof ObjEntity) {
                    validator.validateEntity(
                            validationBuffer,
                            (ObjEntity) classObj,
                            false);
                }
                else if (classObj instanceof Embeddable) {
                    validator.validateEmbeddable(validationBuffer, (Embeddable) classObj);
                }
            }

        }

        this.validation = validationBuffer;
    }

    public boolean updateSelection(Predicate<Object> predicate) {
        boolean modified = false;

        for (Object classObj : classes) {
            boolean select = predicate.test(classObj);
            if (classObj instanceof ObjEntity) {

                if (select) {
                    if(selectedEntities.add(((ObjEntity) classObj).getName())) {
                        modified = true;
                    }
                }
                else {
                    if(selectedEntities.remove(((ObjEntity) classObj).getName())) {
                        modified = true;
                    }
                }
            }
            else if (classObj instanceof Embeddable) {
                if (select) {
                    if(selectedEmbeddables.add(((Embeddable) classObj).getClassName())) {
                        modified = true;
                    }
                }
                else {
                    if(selectedEmbeddables.remove(((Embeddable) classObj).getClassName())) {
                        modified = true;
                    }
                }
            } else if (classObj instanceof DataMap) {
                updateArtifactGenerationMode(classObj, select);
                if(select) {
                    if(isDataMapSelected.add(((DataMap) classObj).getName())) {
                        modified = true;
                    }
                } else {
                    if(isDataMapSelected.remove(((DataMap) classObj).getName())) {
                        modified = true;
                    }
                }
            }

        }

        if (modified) {
            firePropertyChange(SELECTED_PROPERTY, null, null);
        }

        return modified;
    }

    private List<Embeddable> getSelectedEmbeddables() {
        List<Embeddable> selected = new ArrayList<>(selectedEmbeddables.size());
        for (Object classObj : classes) {
            if(classObj instanceof Embeddable) {
                String name = ((Embeddable) classObj).getClassName();
                if(selectedEmbeddables.contains(name)) {
                    selected.add((Embeddable) classObj);
                }
            }
        }

        return selected;
    }

    private List<ObjEntity> getSelectedEntities() {
        List<ObjEntity> selected = new ArrayList<>(selectedEntities.size());
        for (Object classObj : classes) {
            if(classObj instanceof ObjEntity) {
                String name = ((ObjEntity) classObj).getName();
                if(selectedEntities.contains(name)) {
                    selected.add(((ObjEntity) classObj));
                }
            }
        }

        return selected;
    }

    /**
     * Returns the first encountered validation problem for an antity matching the name or
     * null if the entity is valid or the entity is not present.
     */
    public String getProblem(Object obj) {

        String name = null;

        if (obj instanceof ObjEntity) {
            name = ((ObjEntity) obj).getName();
        }
        else if (obj instanceof Embeddable) {
            name = ((Embeddable) obj).getClassName();
        }

        if (validation == null) {
            return null;
        }

        List failures = validation.getFailures(name);
        if (failures.isEmpty()) {
            return null;
        }

        return ((ValidationFailure) failures.get(0)).getDescription();
    }

    public boolean isSelected() {
        if (currentClass instanceof ObjEntity) {
            return selectedEntities
                    .contains(((ObjEntity) currentClass).getName());
        }
        if (currentClass instanceof Embeddable) {
            return selectedEmbeddables
                    .contains(((Embeddable) currentClass).getClassName());
        }
        if(currentClass instanceof DataMap) {
            return isDataMapSelected
                    .contains(((DataMap) currentClass).getName());
        }
        return false;
    }

    public void setSelected(boolean selectedFlag) {
        if (currentClass == null) {
            return;
        }
        if (currentClass instanceof ObjEntity) {
            if (selectedFlag) {
                if (selectedEntities.add(((ObjEntity) currentClass).getName())) {
                    firePropertyChange(SELECTED_PROPERTY, null, null);
                }
            } else {
                if (selectedEntities.remove(((ObjEntity) currentClass).getName())) {
                    firePropertyChange(SELECTED_PROPERTY, null, null);
                }
            }
        }
        if (currentClass instanceof Embeddable) {
            if (selectedFlag) {
                if (selectedEmbeddables.add(((Embeddable) currentClass).getClassName())) {
                    firePropertyChange(SELECTED_PROPERTY, null, null);
                }
            } else {
                if (selectedEmbeddables
                        .remove(((Embeddable) currentClass).getClassName())) {
                    firePropertyChange(SELECTED_PROPERTY, null, null);
                }
            }
        }
        if(currentClass instanceof DataMap) {
            updateArtifactGenerationMode(currentClass, selectedFlag);
            if(selectedFlag) {
                if(isDataMapSelected.add(dataMap.getName())) {
                    firePropertyChange(SELECTED_PROPERTY, null, null);
                }
            } else {
                if(isDataMapSelected
                        .remove(((DataMap) currentClass).getName())) {
                    firePropertyChange(SELECTED_PROPERTY, null, null);
                }
            }
        }
    }

    private void updateArtifactGenerationMode(Object classObj, boolean selected) {
        DataMap dataMap = (DataMap) classObj;
        CgenConfiguration cgenConfiguration = projectController.getApplication().getMetaData().get(dataMap, CgenConfiguration.class);
        if(selected) {
            cgenConfiguration.setArtifactsGenerationMode("all");
        } else {
            cgenConfiguration.setArtifactsGenerationMode("entity");
        }
    }

    public JLabel getItemName(Object obj) {
        String className;
        Icon icon;
        if (obj instanceof Embeddable) {
            className = ((Embeddable) obj).getClassName();
            icon = CellRenderers.iconForObject(new Embeddable());
        } else if(obj instanceof ObjEntity) {
            className = ((ObjEntity) obj).getName();
            icon = CellRenderers.iconForObject(new ObjEntity());
        } else {
            className = ((DataMap) obj).getName();
            icon = CellRenderers.iconForObject(new DataMap());
        }
        JLabel labelIcon = new JLabel();
        labelIcon.setIcon(icon);
        labelIcon.setVisible(true);
        labelIcon.setText(className);
        return labelIcon;
    }

    public void updateSelectedEntities(){
        updateEntities();
        updateEmbeddables();
    }

    CgenConfiguration getCurrentConfiguration() {
        DataMap map = getProjectController().getCurrentDataMap();
        return projectController.getApplication().getMetaData().get(map, CgenConfiguration.class);
    }

    private void updateEntities() {
        CgenConfiguration cgenConfiguration = getCurrentConfiguration();
        if(cgenConfiguration != null) {
            cgenConfiguration.getEntities().clear();
            for(ObjEntity entity: getSelectedEntities()) {
                cgenConfiguration.loadEntity(entity);
            }
        }
    }

    private void updateEmbeddables() {
        CgenConfiguration cgenConfiguration = getCurrentConfiguration();
        if(cgenConfiguration != null) {
            cgenConfiguration.getEmbeddables().clear();
            for(Embeddable embeddable : getSelectedEmbeddables()) {
                cgenConfiguration.loadEmbeddable(embeddable.getClassName());
            }
        }
    }

    private void addToSelectedEntities(Collection<String> entities) {
        selectedEntities.addAll(entities);
        updateEntities();
    }

    void addEntity(DataMap dataMap, ObjEntity objEntity) {
        prepareClasses(dataMap);
        selectedEntities.add(objEntity.getName());
        CgenConfiguration cgenConfiguration = getCurrentConfiguration();
        if(cgenConfiguration != null) {
            cgenConfiguration.loadEntity(objEntity);
        }
    }

    private void addToSelectedEmbeddables(Collection<String> embeddables) {
        selectedEmbeddables.addAll(embeddables);
        updateEmbeddables();
    }

    void addEmbeddable(DataMap dataMap, Embeddable embeddable) {
        prepareClasses(dataMap);
        selectedEmbeddables.add(embeddable.getClassName());
        CgenConfiguration cgenConfiguration = getCurrentConfiguration();
        if(cgenConfiguration != null) {
            cgenConfiguration.loadEmbeddable(embeddable.getClassName());
        }
    }

    public int getSelectedEntitiesSize() {
        return selectedEntities != null ? selectedEntities.size() : 0;
    }

    public int getSelectedEmbeddablesSize() {
        return selectedEmbeddables != null ? selectedEmbeddables.size() : 0;
    }

    public boolean isDataMapSelected() {
        return isDataMapSelected != null && isDataMapSelected.size() == 1;
    }

    public DataMap getDataMap() {
        return dataMap;
    }

    public ProjectController getProjectController() {
        return projectController;
    }

    public Object getCurrentClass() {
        return currentClass;
    }

    public void setCurrentClass(Object currentClass) {
        this.currentClass = currentClass;
    }

    public boolean isInitFromModel() {
        return initFromModel;
    }

    public void setInitFromModel(boolean initFromModel) {
        this.initFromModel = initFromModel;
    }


    public abstract void enableGenerateButton(boolean enabled);

    void removeFromSelectedEntities(ObjEntity objEntity) {
        initCollectionsForSelection(objEntity.getDataMap());
        selectedEntities.remove(objEntity.getName());
    }

    void removeFromSelectedEmbeddables(Embeddable embeddable) {
        initCollectionsForSelection(embeddable.getDataMap());
        selectedEmbeddables.remove(embeddable.getClassName());
    }
}
