/*
 * 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
 *
 * http://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.ofbiz.webtools.artifactinfo;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;

import javax.xml.parsers.ParserConfigurationException;

import javolution.util.FastSet;

import org.ofbiz.base.component.ComponentConfig;
import org.ofbiz.base.concurrent.ExecutionPool;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.FileUtil;
import org.ofbiz.base.util.GeneralException;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.cache.UtilCache;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.DelegatorFactory;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.config.model.DelegatorElement;
import org.ofbiz.entity.config.model.EntityConfig;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.model.ModelReader;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ServiceContainer;
import org.ofbiz.service.eca.ServiceEcaRule;
import org.ofbiz.webapp.control.ConfigXMLReader;
import org.ofbiz.webapp.control.ConfigXMLReader.ControllerConfig;
import org.ofbiz.webapp.control.WebAppConfigurationException;
import org.ofbiz.widget.model.FormFactory;
import org.ofbiz.widget.model.ModelForm;
import org.ofbiz.widget.model.ModelScreen;
import org.ofbiz.widget.model.ScreenFactory;
import org.xml.sax.SAXException;

public class ArtifactInfoFactory {

    public static final String module = ArtifactInfoFactory.class.getName();

    private static final UtilCache<String, ArtifactInfoFactory> artifactInfoFactoryCache = UtilCache.createUtilCache("ArtifactInfoFactory");

    public static final String EntityInfoTypeId = "entity";
    public static final String ServiceInfoTypeId = "service";
    public static final String ServiceEcaInfoTypeId = "serviceEca";
    public static final String FormWidgetInfoTypeId = "form";
    public static final String ScreenWidgetInfoTypeId = "screen";
    public static final String ControllerRequestInfoTypeId = "request";
    public static final String ControllerViewInfoTypeId = "view";

    protected final String delegatorName;
    protected final ModelReader entityModelReader;
    protected final DispatchContext dispatchContext;

    public Map<String, EntityArtifactInfo> allEntityInfos = new ConcurrentHashMap<String, EntityArtifactInfo>();
    public Map<String, ServiceArtifactInfo> allServiceInfos = new ConcurrentHashMap<String, ServiceArtifactInfo>();
    public Map<ServiceEcaRule, ServiceEcaArtifactInfo> allServiceEcaInfos = new ConcurrentHashMap<ServiceEcaRule, ServiceEcaArtifactInfo>();
    public Map<String, FormWidgetArtifactInfo> allFormInfos = new ConcurrentHashMap<String, FormWidgetArtifactInfo>();
    public Map<String, ScreenWidgetArtifactInfo> allScreenInfos = new ConcurrentHashMap<String, ScreenWidgetArtifactInfo>();
    public Map<String, ControllerRequestArtifactInfo> allControllerRequestInfos = new ConcurrentHashMap<String, ControllerRequestArtifactInfo>();
    public Map<String, ControllerViewArtifactInfo> allControllerViewInfos = new ConcurrentHashMap<String, ControllerViewArtifactInfo>();

    // reverse-associative caches for walking backward in the diagram
    public Map<String, Set<ServiceEcaArtifactInfo>> allServiceEcaInfosReferringToServiceName = new ConcurrentHashMap<String, Set<ServiceEcaArtifactInfo>>();
    public Map<String, Set<ServiceArtifactInfo>> allServiceInfosReferringToServiceName = new ConcurrentHashMap<String, Set<ServiceArtifactInfo>>();
    public Map<String, Set<FormWidgetArtifactInfo>> allFormInfosReferringToServiceName = new ConcurrentHashMap<String, Set<FormWidgetArtifactInfo>>();
    public Map<String, Set<FormWidgetArtifactInfo>> allFormInfosBasedOnServiceName = new ConcurrentHashMap<String, Set<FormWidgetArtifactInfo>>();
    public Map<String, Set<ScreenWidgetArtifactInfo>> allScreenInfosReferringToServiceName = new ConcurrentHashMap<String, Set<ScreenWidgetArtifactInfo>>();
    public Map<String, Set<ControllerRequestArtifactInfo>> allRequestInfosReferringToServiceName = new ConcurrentHashMap<String, Set<ControllerRequestArtifactInfo>>();

    public Map<String, Set<ServiceArtifactInfo>> allServiceInfosReferringToEntityName = new ConcurrentHashMap<String, Set<ServiceArtifactInfo>>();
    public Map<String, Set<FormWidgetArtifactInfo>> allFormInfosReferringToEntityName = new ConcurrentHashMap<String, Set<FormWidgetArtifactInfo>>();
    public Map<String, Set<ScreenWidgetArtifactInfo>> allScreenInfosReferringToEntityName = new ConcurrentHashMap<String, Set<ScreenWidgetArtifactInfo>>();

    public Map<ServiceEcaRule, Set<ServiceArtifactInfo>> allServiceInfosReferringToServiceEcaRule = new ConcurrentHashMap<ServiceEcaRule, Set<ServiceArtifactInfo>>();

    public Map<String, Set<FormWidgetArtifactInfo>> allFormInfosExtendingForm = new ConcurrentHashMap<String, Set<FormWidgetArtifactInfo>>();
    public Map<String, Set<ScreenWidgetArtifactInfo>> allScreenInfosReferringToForm = new ConcurrentHashMap<String, Set<ScreenWidgetArtifactInfo>>();

    public Map<String, Set<ScreenWidgetArtifactInfo>> allScreenInfosReferringToScreen = new ConcurrentHashMap<String, Set<ScreenWidgetArtifactInfo>>();
    public Map<String, Set<ControllerViewArtifactInfo>> allViewInfosReferringToScreen = new ConcurrentHashMap<String, Set<ControllerViewArtifactInfo>>();

    public Map<String, Set<ControllerRequestArtifactInfo>> allRequestInfosReferringToView = new ConcurrentHashMap<String, Set<ControllerRequestArtifactInfo>>();

    public Map<String, Set<FormWidgetArtifactInfo>> allFormInfosTargetingRequest = new ConcurrentHashMap<String, Set<FormWidgetArtifactInfo>>();
    public Map<String, Set<FormWidgetArtifactInfo>> allFormInfosReferringToRequest = new ConcurrentHashMap<String, Set<FormWidgetArtifactInfo>>();
    public Map<String, Set<ScreenWidgetArtifactInfo>> allScreenInfosReferringToRequest = new ConcurrentHashMap<String, Set<ScreenWidgetArtifactInfo>>();
    public Map<String, Set<ControllerRequestArtifactInfo>> allRequestInfosReferringToRequest = new ConcurrentHashMap<String, Set<ControllerRequestArtifactInfo>>();

    public static ArtifactInfoFactory getArtifactInfoFactory(String delegatorName) throws GeneralException {
        if (UtilValidate.isEmpty(delegatorName)) {
            delegatorName = "default";
        }

        ArtifactInfoFactory aif = artifactInfoFactoryCache.get(delegatorName);
        if (aif == null) {
            aif = artifactInfoFactoryCache.putIfAbsentAndGet(delegatorName, new ArtifactInfoFactory(delegatorName));
        }
        return aif;
    }

    protected ArtifactInfoFactory(String delegatorName) throws GeneralException {
        this.delegatorName = delegatorName;
        this.entityModelReader = ModelReader.getModelReader(delegatorName);
        DelegatorElement delegatorInfo = EntityConfig.getInstance().getDelegator(delegatorName);
        String modelName = "main";
        if (delegatorInfo != null) {
            modelName = delegatorInfo.getEntityModelReader();
        }
        Delegator delegator = DelegatorFactory.getDelegator(delegatorName);
        LocalDispatcher dispatcher = ServiceContainer.getLocalDispatcher(modelName, delegator);
        this.dispatchContext = dispatcher.getDispatchContext();
        this.prepareAll();
    }

    public void prepareAll() throws GeneralException {
        Debug.logInfo("Loading artifact info objects...", module);
        List<Future<Void>> futures = new ArrayList<Future<Void>>();
        Set<String> entityNames = this.getEntityModelReader().getEntityNames();
        for (String entityName: entityNames) {
            this.getEntityArtifactInfo(entityName);
        }

        Set<String> serviceNames = this.getDispatchContext().getAllServiceNames();
        for (String serviceName: serviceNames) {
            futures.add(ExecutionPool.GLOBAL_FORK_JOIN.submit(prepareTaskForServiceAnalysis(serviceName)));
        }
        // how to get all Service ECAs to prepare? don't worry about it, will be populated from service load, ie all ECAs for each service

        Collection<ComponentConfig> componentConfigs = ComponentConfig.getAllComponents();
        ExecutionPool.getAllFutures(futures);
        futures = new ArrayList<Future<Void>>();
        for (ComponentConfig componentConfig: componentConfigs) {
            futures.add(ExecutionPool.GLOBAL_FORK_JOIN.submit(prepareTaskForComponentAnalysis(componentConfig)));
        }
        ExecutionPool.getAllFutures(futures);
        Debug.logInfo("Artifact info objects loaded.", module);
    }

    public ModelReader getEntityModelReader() {
        return this.entityModelReader;
    }

    public DispatchContext getDispatchContext() {
        return this.dispatchContext;
    }

    public ModelEntity getModelEntity(String entityName) throws GenericEntityException {
        return this.getEntityModelReader().getModelEntity(entityName);
    }

    public ModelService getModelService(String serviceName) throws GenericServiceException {
        return this.getDispatchContext().getModelService(serviceName);
    }

    public ModelForm getModelForm(String formNameAndLocation) throws ParserConfigurationException, SAXException, IOException {
        return getModelForm(formNameAndLocation.substring(formNameAndLocation.indexOf("#") + 1), formNameAndLocation.substring(0, formNameAndLocation.indexOf("#")));
    }
    public ModelForm getModelForm(String formName, String formLocation) throws ParserConfigurationException, SAXException, IOException {
        return FormFactory.getFormFromLocation(formLocation, formName, this.entityModelReader, this.dispatchContext);
    }

    public ModelScreen getModelScreen(String screenName, String screenLocation) throws ParserConfigurationException, SAXException, IOException {
        return ScreenFactory.getScreenFromLocation(screenLocation, screenName);
    }

    public ConfigXMLReader.RequestMap getControllerRequestMap(URL controllerXmlUrl, String requestUri) {
        try {
            return ConfigXMLReader.getControllerConfig(controllerXmlUrl).getRequestMapMap().get(requestUri);
        } catch (WebAppConfigurationException e) {
            Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module);
        }
        return null;
    }

    public ConfigXMLReader.ViewMap getControllerViewMap(URL controllerXmlUrl, String viewUri) {
        ControllerConfig cc;
        try {
            cc = ConfigXMLReader.getControllerConfig(controllerXmlUrl);
            return cc.getViewMapMap().get(viewUri);
        } catch (WebAppConfigurationException e) {
            Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module);
        }
        return null;
    }

    public EntityArtifactInfo getEntityArtifactInfo(String entityName) throws GeneralException {
        EntityArtifactInfo curInfo = this.allEntityInfos.get(entityName);
        if (curInfo == null) {
            curInfo = new EntityArtifactInfo(entityName, this);
            this.allEntityInfos.put(entityName, curInfo);
            curInfo.populateAll();
        }
        return curInfo;
    }

    public ServiceArtifactInfo getServiceArtifactInfo(String serviceName) throws GeneralException {
        ServiceArtifactInfo curInfo = this.allServiceInfos.get(serviceName);
        if (curInfo == null) {
            curInfo = new ServiceArtifactInfo(serviceName, this);
            this.allServiceInfos.put(serviceName, curInfo);
            curInfo.populateAll();
        }
        return curInfo;
    }

    public ServiceEcaArtifactInfo getServiceEcaArtifactInfo(ServiceEcaRule ecaRule) throws GeneralException {
        ServiceEcaArtifactInfo curInfo = this.allServiceEcaInfos.get(ecaRule);
        if (curInfo == null) {
            curInfo = new ServiceEcaArtifactInfo(ecaRule, this);
            this.allServiceEcaInfos.put(ecaRule, curInfo);
            curInfo.populateAll();
        }
        return curInfo;
    }

    public FormWidgetArtifactInfo getFormWidgetArtifactInfo(String formNameAndLocation) throws GeneralException {
        return getFormWidgetArtifactInfo(formNameAndLocation.substring(formNameAndLocation.indexOf("#") + 1), formNameAndLocation.substring(0, formNameAndLocation.indexOf("#")));
    }
    public FormWidgetArtifactInfo getFormWidgetArtifactInfo(String formName, String formLocation) throws GeneralException {
        FormWidgetArtifactInfo curInfo = this.allFormInfos.get(formLocation + "#" + formName);
        if (curInfo == null) {
            curInfo = new FormWidgetArtifactInfo(formName, formLocation, this);
            this.allFormInfos.put(curInfo.getUniqueId(), curInfo);
            curInfo.populateAll();
        }
        return curInfo;
    }

    public ScreenWidgetArtifactInfo getScreenWidgetArtifactInfo(String screenName, String screenLocation) {
        ScreenWidgetArtifactInfo curInfo = this.allScreenInfos.get(screenLocation + "#" + screenName);
        if (curInfo == null) {
            try {
                curInfo = new ScreenWidgetArtifactInfo(screenName, screenLocation, this);
                this.allScreenInfos.put(curInfo.getUniqueId(), curInfo);
                curInfo.populateAll();
            } catch (GeneralException e) {
                Debug.logWarning("Error loading screen [" + screenName + "] from resource [" + screenLocation + "]: " + e.toString(), module);
                return null;
            }
        }
        return curInfo;
    }

    public ControllerRequestArtifactInfo getControllerRequestArtifactInfo(URL controllerXmlUrl, String requestUri) throws GeneralException {
        if (controllerXmlUrl == null) {
            throw new GeneralException("Got a null URL controller");
        }
        if (requestUri == null) {
            throw new GeneralException("Got a null requestUri for controller: " + controllerXmlUrl);
        }
        ControllerRequestArtifactInfo curInfo = this.allControllerRequestInfos.get(controllerXmlUrl.toExternalForm() + "#" + requestUri);
        if (curInfo == null) {
            curInfo = new ControllerRequestArtifactInfo(controllerXmlUrl, requestUri, this);
            this.allControllerRequestInfos.put(curInfo.getUniqueId(), curInfo);
            curInfo.populateAll();
        }
        return curInfo;
    }

    public ControllerViewArtifactInfo getControllerViewArtifactInfo(URL controllerXmlUrl, String viewUri) throws GeneralException {
        ControllerViewArtifactInfo curInfo = this.allControllerViewInfos.get(controllerXmlUrl.toExternalForm() + "#" + viewUri);
        if (curInfo == null) {
            curInfo = new ControllerViewArtifactInfo(controllerXmlUrl, viewUri, this);
            this.allControllerViewInfos.put(curInfo.getUniqueId(), curInfo);
        }
        return curInfo;
    }

    public ArtifactInfoBase getArtifactInfoByUniqueIdAndType(String uniqueId, String type) {
        if (uniqueId.contains("#")) {
            int poundIndex = uniqueId.indexOf('#');
            return getArtifactInfoByNameAndType(uniqueId.substring(poundIndex+1), uniqueId.substring(0, poundIndex), type);
        } else {
            return getArtifactInfoByNameAndType(uniqueId, null, type);
        }
    }

    public ArtifactInfoBase getArtifactInfoByNameAndType(String artifactName, String artifactLocation, String type) {
        try {
            if ("entity".equals(type)) {
                return this.getEntityArtifactInfo(artifactName);
            } else if ("service".equals(type)) {
                return this.getServiceArtifactInfo(artifactName);
            } else if ("form".equals(type)) {
                return this.getFormWidgetArtifactInfo(artifactName, artifactLocation);
            } else if ("screen".equals(type)) {
                return this.getScreenWidgetArtifactInfo(artifactName, artifactLocation);
            } else if ("request".equals(type)) {
                return this.getControllerRequestArtifactInfo(new URL(artifactLocation), artifactName);
            } else if ("view".equals(type)) {
                return this.getControllerViewArtifactInfo(new URL(artifactLocation), artifactName);
            }
        } catch (GeneralException e) {
            Debug.logError(e, "Error getting artifact info: " + e.toString(), module);
        } catch (MalformedURLException e) {
            Debug.logError(e, "Error getting artifact info: " + e.toString(), module);
        }
        return null;
    }

    public Set<ArtifactInfoBase> getAllArtifactInfosByNamePartial(String artifactNamePartial, String type) {
        Set<ArtifactInfoBase> aiBaseSet = FastSet.newInstance();

        if (UtilValidate.isEmpty(artifactNamePartial)) {
            return aiBaseSet;
        }

        if (UtilValidate.isEmpty(type) || "entity".equals(type)) {
            for (Map.Entry<String, EntityArtifactInfo> curEntry: allEntityInfos.entrySet()) {
                if (curEntry.getKey().toUpperCase().contains(artifactNamePartial.toUpperCase())) {
                    aiBaseSet.add(curEntry.getValue());
                }
            }
        }
        if (UtilValidate.isEmpty(type) || "service".equals(type)) {
            for (Map.Entry<String, ServiceArtifactInfo> curEntry: allServiceInfos.entrySet()) {
                if (curEntry.getKey().toUpperCase().contains(artifactNamePartial.toUpperCase())) {
                    aiBaseSet.add(curEntry.getValue());
                }
            }
        }
        if (UtilValidate.isEmpty(type) || "form".equals(type)) {
            for (Map.Entry<String, FormWidgetArtifactInfo> curEntry: allFormInfos.entrySet()) {
                if (curEntry.getKey().toUpperCase().contains(artifactNamePartial.toUpperCase())) {
                    aiBaseSet.add(curEntry.getValue());
                }
            }
        }
        if (UtilValidate.isEmpty(type) || "screen".equals(type)) {
            for (Map.Entry<String, ScreenWidgetArtifactInfo> curEntry: allScreenInfos.entrySet()) {
                if (curEntry.getKey().toUpperCase().contains(artifactNamePartial.toUpperCase())) {
                    aiBaseSet.add(curEntry.getValue());
                }
            }
        }
        if (UtilValidate.isEmpty(type) || "request".equals(type)) {
            for (Map.Entry<String, ControllerRequestArtifactInfo> curEntry: allControllerRequestInfos.entrySet()) {
                if (curEntry.getKey().toUpperCase().contains(artifactNamePartial.toUpperCase())) {
                    aiBaseSet.add(curEntry.getValue());
                }
            }
        }
        if (UtilValidate.isEmpty(type) || "view".equals(type)) {
            for (Map.Entry<String, ControllerViewArtifactInfo> curEntry: allControllerViewInfos.entrySet()) {
                if (curEntry.getKey().toUpperCase().contains(artifactNamePartial.toUpperCase())) {
                    aiBaseSet.add(curEntry.getValue());
                }
            }
        }

        return aiBaseSet;
    }

    // private methods
    @SuppressWarnings("unchecked")
    private Callable<Void> prepareTaskForServiceAnalysis(final String serviceName) {
        return new Callable() {
            @Override
            public Callable<Void> call() throws Exception {
                try {
                    getServiceArtifactInfo(serviceName);
                } catch(Exception exc) {
                    Debug.logWarning(exc, "Error processing service: " + serviceName, module);
                }
                return null;
            }
        };
    }

    @SuppressWarnings("unchecked")
    private Callable<Void> prepareTaskForComponentAnalysis(final ComponentConfig componentConfig) {
        return new Callable() {
            @Override
            public Callable<Void> call() throws Exception {
                String componentName = componentConfig.getGlobalName();
                String rootComponentPath = componentConfig.getRootLocation();
                List<File> screenFiles = new ArrayList<File>();
                List<File> formFiles = new ArrayList<File>();
                List<File> controllerFiles = new ArrayList<File>();
                try {
                    screenFiles = FileUtil.findXmlFiles(rootComponentPath, null, "screens", "widget-screen.xsd");
                } catch (IOException ioe) {
                    Debug.logWarning(ioe.getMessage(), module);
                }
                try {
                    formFiles = FileUtil.findXmlFiles(rootComponentPath, null, "forms", "widget-form.xsd");
                } catch (IOException ioe) {
                    Debug.logWarning(ioe.getMessage(), module);
                }
                try {
                    controllerFiles = FileUtil.findXmlFiles(rootComponentPath, null, "site-conf", "site-conf.xsd");
                } catch (IOException ioe) {
                    Debug.logWarning(ioe.getMessage(), module);
                }
                for (File screenFile: screenFiles) {
                    String screenFilePath = screenFile.getAbsolutePath();
                    screenFilePath = screenFilePath.replace('\\', '/');
                    String screenFileRelativePath = screenFilePath.substring(rootComponentPath.length());
                    String screenLocation = "component://" + componentName + "/" + screenFileRelativePath;
                    Map<String, ModelScreen> modelScreenMap = null;
                    try {
                        modelScreenMap = ScreenFactory.getScreensFromLocation(screenLocation);
                    } catch (Exception exc) {
                        Debug.logWarning(exc.getMessage(), module);
                    }
                    for (String screenName : modelScreenMap.keySet()) {
                        getScreenWidgetArtifactInfo(screenName, screenLocation);
                    }
                }
                for (File formFile: formFiles) {
                    String formFilePath = formFile.getAbsolutePath();
                    formFilePath = formFilePath.replace('\\', '/');
                    String formFileRelativePath = formFilePath.substring(rootComponentPath.length());
                    String formLocation = "component://" + componentName + "/" + formFileRelativePath;
                    Map<String, ModelForm> modelFormMap = null;
                    try {
                        modelFormMap = FormFactory.getFormsFromLocation(formLocation, getEntityModelReader(), getDispatchContext());
                    } catch (Exception exc) {
                        Debug.logWarning(exc.getMessage(), module);
                    }
                    for (String formName : modelFormMap.keySet()) {
                        try {
                            getFormWidgetArtifactInfo(formName, formLocation);
                        } catch (GeneralException ge) {
                            Debug.logWarning(ge.getMessage(), module);
                        }
                    }
                }
                for (File controllerFile: controllerFiles) {
                    URL controllerUrl = null;
                    try {
                        controllerUrl = controllerFile.toURI().toURL();
                    } catch (MalformedURLException mue) {
                        Debug.logWarning(mue.getMessage(), module);
                    }
                    if (controllerUrl == null) continue;
                    ControllerConfig cc = ConfigXMLReader.getControllerConfig(controllerUrl);
                    for (String requestUri: cc.getRequestMapMap().keySet()) {
                        try {
                            getControllerRequestArtifactInfo(controllerUrl, requestUri);
                        } catch (GeneralException e) {
                            Debug.logWarning(e.getMessage(), module);
                        }
                    }
                    for (String viewUri: cc.getViewMapMap().keySet()) {
                        try {
                            getControllerViewArtifactInfo(controllerUrl, viewUri);
                        } catch (GeneralException e) {
                            Debug.logWarning(e.getMessage(), module);
                        }
                    }
                }
                return null;
            }
        };
    }

}
