/*****************************************************************
 *   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.JOptionPane;
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.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Predicate;
import java.util.prefs.Preferences;
import java.util.stream.Collectors;

import org.apache.cayenne.configuration.event.DataMapEvent;
import org.apache.cayenne.configuration.event.DataMapListener;
import org.apache.cayenne.configuration.xml.DataChannelMetaData;
import org.apache.cayenne.dbsync.reverse.configuration.ToolsModule;
import org.apache.cayenne.di.DIBootstrap;
import org.apache.cayenne.di.Module;
import org.apache.cayenne.di.spi.ModuleLoader;
import org.apache.cayenne.gen.CgenConfiguration;
import org.apache.cayenne.gen.ClassGenerationAction;
import org.apache.cayenne.gen.ClassGenerationActionFactory;
import org.apache.cayenne.gen.ClientClassGenerationAction;
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.map.event.EmbeddableEvent;
import org.apache.cayenne.map.event.EmbeddableListener;
import org.apache.cayenne.map.event.EntityEvent;
import org.apache.cayenne.map.event.ObjEntityListener;
import org.apache.cayenne.modeler.ProjectController;
import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
import org.apache.cayenne.modeler.dialog.pref.GeneralPreferences;
import org.apache.cayenne.modeler.editor.DbImportController;
import org.apache.cayenne.modeler.util.CayenneController;
import org.apache.cayenne.modeler.util.ModelerUtil;
import org.apache.cayenne.swing.BindingBuilder;
import org.apache.cayenne.tools.CayenneToolsModuleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @since 4.1
 * A controller for the class generator dialog.
 */
public class CodeGeneratorController extends CayenneController implements ObjEntityListener, EmbeddableListener, DataMapListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(ErrorDebugDialog.class);

    public static final String SELECTED_PROPERTY = "selected";

    protected ProjectController projectController;

    protected List<Object> classes;
    protected SelectionModel selectionModel;
    protected Object currentClass;

    protected boolean initFromModel;

    protected CodeGeneratorPane view;

    protected ClassesTabController classesSelector;
    protected GeneratorTabController generatorSelector;
    private ConcurrentMap<DataMap, GeneratorController> prevGeneratorController;

    public CodeGeneratorController(ProjectController projectController) {
        super(projectController);
        this.classesSelector = new ClassesTabController(this);
        this.generatorSelector = new GeneratorTabController(this);
        this.view = new CodeGeneratorPane(generatorSelector.getView(), classesSelector.getView());
        this.prevGeneratorController = new ConcurrentHashMap<>();
        this.projectController = projectController;
        this.classes = new ArrayList<>();
        this.selectionModel = new SelectionModel();
        initBindings();
        initListeners();
    }

    public void initFromModel() {
        initFromModel = true;
        prepareClasses(projectController.getCurrentDataMap());
        DataMap dataMap = projectController.getCurrentDataMap();
        classesSelectedAction();
        CgenConfiguration cgenConfiguration = createConfiguration();
        GeneratorController modeController = prevGeneratorController.get(dataMap) != null
                        ? prevGeneratorController.get(dataMap)
                        : isDefaultConfig(cgenConfiguration)
                            ? cgenConfiguration.isClient()
                                ? generatorSelector.getClientGeneratorController()
                                : generatorSelector.getStandartController()
                            : generatorSelector.getCustomModeController();

        prevGeneratorController.put(dataMap, modeController);
        generatorSelector.setSelectedController(modeController);
        classesSelector.startup();
        initFromModel = false;
        classesSelector.validate(classes);
    }

    private boolean isDefaultConfig(CgenConfiguration cgenConfiguration) {
        return cgenConfiguration.isMakePairs() && cgenConfiguration.isUsePkgPath() &&
                !cgenConfiguration.isOverwrite() && !cgenConfiguration.isCreatePKProperties() &&
                !cgenConfiguration.isCreatePropertyNames() && cgenConfiguration.getOutputPattern().equals("*.java") &&
                (cgenConfiguration.getTemplate().equals(ClassGenerationAction.SUBCLASS_TEMPLATE) ||
                        cgenConfiguration.getTemplate().equals(ClientClassGenerationAction.SUBCLASS_TEMPLATE)) &&
                (cgenConfiguration.getSuperTemplate().equals(ClassGenerationAction.SUPERCLASS_TEMPLATE) ||
                        cgenConfiguration.getSuperTemplate().equals(ClientClassGenerationAction.SUPERCLASS_TEMPLATE)) &&
                (cgenConfiguration.getSuperPkg() == null || cgenConfiguration.getSuperPkg().isEmpty());

    }

    private void initListeners(){
        projectController.addObjEntityListener(this);
        projectController.addEmbeddableListener(this);
        projectController.addDataMapListener(this);
    }

    @Override
    public CodeGeneratorPane getView() {
        return view;
    }

    protected void initBindings() {
        BindingBuilder builder = new BindingBuilder(getApplication().getBindingFactory(), this);

        builder.bindToAction(view.getGenerateButton(), "generateAction()");
        builder.bindToAction(this, "classesSelectedAction()", SELECTED_PROPERTY);
        builder.bindToAction(generatorSelector, "generatorSelectedAction()",
                GeneratorTabController.GENERATOR_PROPERTY);

        generatorSelectedAction();
    }

    public void generatorSelectedAction() {
        GeneratorController controller = generatorSelector.getGeneratorController();
        classesSelector.validate(classes);

        Predicate<Object> defaultPredicate = object -> {
            if (object instanceof ObjEntity) {
                return classesSelector.getProblem(((ObjEntity) object).getName()) == null;
            }

            if (object instanceof Embeddable) {
                return classesSelector.getProblem(((Embeddable) object).getClassName()) == null;
            }
            return false;
        };

        Predicate<Object> predicate = controller != null
                ? defaultPredicate
                : o -> false;

        updateSelection(predicate);
        classesSelector.classSelectedAction();
    }

    public void classesSelectedAction() {
        if(!isInitFromModel()) {
            getProjectController().setDirty(true);
        }
    }

    public void generateAction() {
        CgenConfiguration cgenConfiguration = createConfiguration();
        List<Module> modules = new ModuleLoader()
                .load(CayenneToolsModuleProvider.class);
        modules.add(binder -> binder.bind(DataChannelMetaData.class)
                .toInstance(projectController.getApplication().getMetaData()));
        ClassGenerationAction generator = DIBootstrap
                .createInjector(modules)
                .getInstance(ClassGenerationActionFactory.class)
                .createAction(cgenConfiguration);

        try {
            generator.prepareArtifacts();
            generator.execute();
            JOptionPane.showMessageDialog(
                    this.getView(),
                    "Class generation finished");
        } catch (Exception e) {
            LOGGER.error("Error generating classes", e);
            JOptionPane.showMessageDialog(
                    this.getView(),
                    "Error generating classes - " + e.getMessage());
        }
    }

    public ConcurrentMap<DataMap, GeneratorController> getPrevGeneratorController() {
        return prevGeneratorController;
    }

    public void enableGenerateButton(boolean enable) {
        view.getGenerateButton().setEnabled(enable);
    }

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

    /**
     * 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());

        // TODO: this should be done in actual generation, not here
        // 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 boolean updateSelection(Predicate<Object> predicate) {
        boolean modified = selectionModel.updateSelection(predicate, classes);

        for (Object classObj : classes) {
            if(classObj instanceof DataMap) {
                boolean select = predicate.test(classObj);
                updateArtifactGenerationMode(classObj, select);
            }
        }

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

        return modified;
    }

    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 boolean isSelected() {
        return selectionModel.isSelected(currentClass);
    }

    public void setSelected(boolean selectedFlag) {
        if (currentClass instanceof DataMap) {
            updateArtifactGenerationMode(currentClass, selectedFlag);
        }
        if (selectionModel.setSelected(currentClass, selectedFlag)) {
            firePropertyChange(SELECTED_PROPERTY, null, null);
        }
    }

    public Object getCurrentClass() {
        return currentClass;
    }

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

    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: selectionModel.getSelectedEntities(classes)) {
                cgenConfiguration.loadEntity(entity);
            }
        }
    }

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

    private void addToSelectedEntities(Collection<String> entities) {
        selectionModel.addSelectedEntities(entities);
        updateEntities();
    }

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

    private void addToSelectedEmbeddables(Collection<String> embeddables) {
        selectionModel.addSelectedEmbeddables(embeddables);
        updateEmbeddables();
    }


    public int getSelectedEntitiesSize() {
        return selectionModel.getSelectedEntitiesCount();
    }

    public int getSelectedEmbeddablesSize() {
        return selectionModel.getSelecetedEmbeddablesCount();
    }

    public boolean isDataMapSelected() {
        return selectionModel.getSelectedDataMapsCount() > 0;
    }

    public ProjectController getProjectController() {
        return projectController;
    }

    public boolean isInitFromModel() {
        return initFromModel;
    }

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

    @Override
    public void objEntityChanged(EntityEvent e) {}

    @Override
    public void objEntityAdded(EntityEvent e) {
        addEntity(e.getEntity().getDataMap(), (ObjEntity) e.getEntity());
    }

    @Override
    public void objEntityRemoved(EntityEvent e) {
        selectionModel.removeFromSelectedEntities((ObjEntity) e.getEntity());
        DataMap map = e.getEntity().getDataMap();
        CgenConfiguration cgenConfiguration = projectController.getApplication().getMetaData().get(map, CgenConfiguration.class);
        if(cgenConfiguration != null) {
            cgenConfiguration.getEntities().remove(e.getEntity().getName());
        }
    }

    @Override
    public void embeddableChanged(EmbeddableEvent e, DataMap map) {}

    @Override
    public void embeddableAdded(EmbeddableEvent e, DataMap map) {
        prepareClasses(map);
        String embeddableClassName = e.getEmbeddable().getClassName();
        selectionModel.addSelectedEmbeddable(embeddableClassName);
        CgenConfiguration cgenConfiguration = getCurrentConfiguration();
        if(cgenConfiguration != null) {
            cgenConfiguration.loadEmbeddable(embeddableClassName);
        }
    }

    @Override
    public void embeddableRemoved(EmbeddableEvent e, DataMap map) {
        selectionModel.removeFromSelectedEmbeddables(e.getEmbeddable());
        CgenConfiguration cgenConfiguration = projectController.getApplication().getMetaData().get(map, CgenConfiguration.class);
        if(cgenConfiguration != null) {
            cgenConfiguration.getEmbeddables().remove(e.getEmbeddable().getClassName());
        }
    }

    @Override
    public void dataMapChanged(DataMapEvent e) {
        if(e.getSource() instanceof DbImportController) {
            CgenConfiguration cgenConfiguration = getCurrentConfiguration();
            if(cgenConfiguration != null) {
                for(ObjEntity objEntity : e.getDataMap().getObjEntities()) {
                    if(!cgenConfiguration.getExcludeEntityArtifacts().contains(objEntity.getName())) {
                        addEntity(cgenConfiguration.getDataMap(), objEntity);
                    }
                }
            }
        }
    }

    @Override
    public void dataMapAdded(DataMapEvent e) {}

    @Override
    public void dataMapRemoved(DataMapEvent e) {}
}
