/*******************************************************************************
 * 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.apache.ofbiz.entity.model;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.model.ModelViewEntity.ComplexAliasMember;
import org.apache.ofbiz.entity.model.ModelViewEntity.ModelAlias;
import org.apache.ofbiz.entity.model.ModelViewEntity.ModelAliasAll;
import org.apache.ofbiz.entity.model.ModelViewEntity.ModelMemberEntity;
import org.apache.ofbiz.entity.model.ModelViewEntity.ModelViewLink;
/**
 * This class is used for declaring Dynamic View Entities, to be used and thrown away.
 * A special method exists on the Delegator to accept a DynamicViewEntity instead
 * of an entity-name.
 *
 */
public class DynamicViewEntity {
    public static final String module = DynamicViewEntity.class.getName();

    /** The entity-name of the Entity */
    protected String entityName = "DynamicViewEntity";

    /** The package-name of the Entity */
    protected String packageName = "org.apache.ofbiz.dynamicview";

    /** The default-resource-name of the Entity, used with the getResource call to check for a value in a resource bundle */
    protected String defaultResourceName = "";

    /** The title for documentation purposes */
    protected String title = "";

    /** Contains member-entity alias name definitions: key is alias, value is ModelMemberEntity */
    protected Map<String, ModelMemberEntity> memberModelMemberEntities = new HashMap<String, ModelMemberEntity>();

    /** List of alias-alls which act as a shortcut for easily pulling over member entity fields */
    protected List<ModelAliasAll> aliasAlls = new ArrayList<ModelAliasAll>();

    /** List of aliases with information in addition to what is in the standard field list */
    protected List<ModelAlias> aliases = new ArrayList<ModelAlias>();

    /** List of fields to group by */
    protected List<String> groupBy;

    /** List of view links to define how entities are connected (or "joined") */
    protected List<ModelViewLink> viewLinks = new ArrayList<ModelViewLink>();

    /** relations defining relationships between this entity and other entities */
    protected List<ModelRelation> relations = new ArrayList<ModelRelation>();

    public DynamicViewEntity() {
    }

    public ModelViewEntity makeModelViewEntity(Delegator delegator) {
        ModelViewEntity modelViewEntity = new ModelViewEntity(this, delegator.getModelReader());
        return modelViewEntity;
    }

    public String getViewXml(String entityName) throws IOException {
        Document doc = UtilXml.makeEmptyXmlDocument();
        Element viewElement = getViewElement(doc, entityName);
        return UtilXml.writeXmlDocument(viewElement);
    }

    public Element getViewElement(Document doc, String entityName) {
        Element viewElement = doc.createElement("view-entity");
        viewElement.setAttribute("entity-name", entityName);

        for (ModelMemberEntity member: memberModelMemberEntities.values()) {
            Element memberElement = doc.createElement("member-entity");
            memberElement.setAttribute("entity-alias", member.getEntityAlias());
            memberElement.setAttribute("entity-name", member.getEntityName());
            viewElement.appendChild(memberElement);
        }
        for (ModelAliasAll aliasAll: aliasAlls) {
            Element aliasAllElement = doc.createElement("alias-all");
            aliasAllElement.setAttribute("entity-alias", aliasAll.getEntityAlias());
            if (UtilValidate.isNotEmpty(aliasAll.getPrefix())) aliasAllElement.setAttribute("prefix", aliasAll.getPrefix());
            if (aliasAll.getGroupBy()) aliasAllElement.setAttribute("group-by", "true");
            if (UtilValidate.isNotEmpty(aliasAll.getFunction())) aliasAllElement.setAttribute("function", aliasAll.getFunction());
            for (String excludeField: aliasAll) {
                Element excludeElement = doc.createElement("exclude");
                excludeElement.setAttribute("field", excludeField);
                aliasAllElement.appendChild(excludeElement);
            }
            viewElement.appendChild(aliasAllElement);
        }
        for (ModelAlias alias: aliases) {
            Element aliasElement = doc.createElement("alias");
            aliasElement.setAttribute("entity-alias", alias.getEntityAlias());
            aliasElement.setAttribute("name", alias.getName());
            if (!alias.getName().equals(alias.getField())) aliasElement.setAttribute("field", alias.getField());
            String colAlias = ModelUtil.dbNameToVarName(alias.getColAlias());
            if (!alias.getName().equals(colAlias)) aliasElement.setAttribute("col-alias", colAlias);
            if (alias.getIsPk() != null) aliasElement.setAttribute("prim-key", alias.getIsPk().toString());
            if (alias.getGroupBy()) aliasElement.setAttribute("group-by", "true");
            if (UtilValidate.isNotEmpty(alias.getFunction())) aliasElement.setAttribute("function", alias.getFunction());
            // TODO: description, complex-alias
            viewElement.appendChild(aliasElement);
        }
        for (ModelViewLink viewLink: viewLinks) {
            Element viewLinkElement = doc.createElement("view-link");
            viewLinkElement.setAttribute("entity-alias", viewLink.getEntityAlias());
            if (viewLink.isRelOptional()) viewLinkElement.setAttribute("rel-optional", "true");
            viewLinkElement.setAttribute("rel-entity-alias", viewLink.getRelEntityAlias());
            for (ModelKeyMap keyMap: viewLink) {
                Element keyMapElement = doc.createElement("key-map");
                keyMapElement.setAttribute("field-name", keyMap.getFieldName());
                if (!keyMap.getFieldName().equals(keyMap.getRelFieldName())) keyMapElement.setAttribute("rel-field-name", keyMap.getRelFieldName());
                viewLinkElement.appendChild(keyMapElement);
            }
            // TODO: conditions
            viewElement.appendChild(viewLinkElement);
        }
        for (ModelRelation relation: relations) {
            viewElement.appendChild(relation.toXmlElement(doc));
        }
        return viewElement;
    }

    public String getOneRealEntityName() {
        // return first entity name for memberModelMemberEntities Map
        if (this.memberModelMemberEntities.size() == 0) {
            return null;
        }

        ModelMemberEntity modelMemberEntity = this.memberModelMemberEntities.entrySet().iterator().next().getValue();
        return modelMemberEntity.getEntityName();
    }

    /** Getter for property entityName.
     * @return Value of property entityName.
     *
     */
    public String getEntityName() {
        return entityName;
    }

    /** Setter for property entityName.
     * @param entityName New value of property entityName.
     *
     */
    public void setEntityName(String entityName) {
        this.entityName = entityName;
    }

    /** Getter for property packageName.
     * @return Value of property packageName.
     *
     */
    public String getPackageName() {
        return packageName;
    }

    /** Setter for property packageName.
     * @param packageName New value of property packageName.
     *
     */
    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    /** Getter for property defaultResourceName.
     * @return Value of property defaultResourceName.
     *
     */
    public String getDefaultResourceName() {
        return defaultResourceName;
    }

    /** Setter for property defaultResourceName.
     * @param defaultResourceName New value of property defaultResourceName.
     *
     */
    public void setDefaultResourceName(String defaultResourceName) {
        this.defaultResourceName = defaultResourceName;
    }

    /** Getter for property title.
     * @return Value of property title.
     *
     */
    public String getTitle() {
        return title;
    }

    /** Setter for property title.
     * @param title New value of property title.
     *
     */
    public void setTitle(String title) {
        this.title = title;
    }

    public void addMemberEntity(String entityAlias, String entityName) {
        ModelMemberEntity modelMemberEntity = new ModelMemberEntity(entityAlias, entityName);
        this.memberModelMemberEntities.put(entityAlias, modelMemberEntity);
    }

    public Iterator<Map.Entry<String, ModelMemberEntity>> getModelMemberEntitiesEntryIter() {
        return this.memberModelMemberEntities.entrySet().iterator();
    }

    /**
     * @deprecated use {@link #addAliasAll(String, String, Collection)}
     */
    @Deprecated
    public void addAliasAll(String entityAlias, String prefix) {
        addAliasAll(entityAlias, prefix, null);
    }

    public void addAliasAll(String entityAlias, String prefix, Collection<String> excludes) {
        ModelAliasAll aliasAll = new ModelAliasAll(entityAlias, prefix, false, null, null, excludes);
        this.aliasAlls.add(aliasAll);
    }

    public void addAllAliasAllsToList(List<ModelAliasAll> addList) {
        addList.addAll(this.aliasAlls);
    }

    public void addAlias(String entityAlias, String name) {
        this.addAlias(entityAlias, name, null, null, null, null, null);
    }

    /** Add an alias, full detail. All parameters can be null except entityAlias and name. */
    public void addAlias(String entityAlias, String name, String field, String colAlias, Boolean primKey, Boolean groupBy, String function) {
        addAlias(entityAlias, name, field, colAlias, primKey, groupBy, function, null, null);
    }

    public void addAlias(String entityAlias, String name, String field, String colAlias, Boolean primKey, Boolean groupBy, String function, ComplexAliasMember complexAliasMember) {
        addAlias(entityAlias, name, field, colAlias, primKey, groupBy, function, null, complexAliasMember);
    }

    public void addAlias(String entityAlias, String name, String field, String colAlias, Boolean primKey, Boolean groupBy, String function, String fieldSet, ComplexAliasMember complexAliasMember) {
        if (entityAlias == null && complexAliasMember == null) {
            throw new IllegalArgumentException("entityAlias cannot be null if this is not a complex alias in call to DynamicViewEntity.addAlias");
        }
        if (name == null) {
            throw new IllegalArgumentException("name cannot be null in call to DynamicViewEntity.addAlias");
        }

        ModelAlias alias = new ModelAlias(entityAlias, name, field, colAlias, primKey, groupBy, function, fieldSet);
        if (complexAliasMember != null) {
            alias.setComplexAliasMember(complexAliasMember);
        }
        this.aliases.add(alias);
    }

    public void addAllAliasesToList(List<ModelAlias> addList) {
        addList.addAll(this.aliases);
    }

    public void addViewLink(String entityAlias, String relEntityAlias, Boolean relOptional, List<ModelKeyMap> modelKeyMaps) {
        ModelViewLink modelViewLink = new ModelViewLink(entityAlias, relEntityAlias, relOptional, null, modelKeyMaps);
        this.viewLinks.add(modelViewLink);
    }

    public void addAllViewLinksToList(List<ModelViewLink> addList) {
        addList.addAll(this.viewLinks);
    }

    public void addRelation(String type, String title, String relEntityName, List<ModelKeyMap> modelKeyMaps) {
        ModelRelation relation = ModelRelation.create(null, null, type, title, relEntityName, null, modelKeyMaps, false);
        this.relations.add(relation);
    }

    public void addAllRelationsToList(List<ModelRelation> addList) {
        addList.addAll(this.relations);
    }

    public void setGroupBy(List<String> groupBy) {
        this.groupBy = groupBy;
    }

    public void addAllGroupByFieldsToList(List<String> addList) {
        if (groupBy != null) {
            addList.addAll(this.groupBy);
        }
    }
}
