/*
 * Copyright (c) 1998, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.oxm.sequenced;

import java.util.List;
import java.util.ArrayList;

import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;

/**
 * <p>Setting objects are used to control the order in which the
 * mappings for Sequenced Objects are processed.</p>
 *
 * <b>Example 1</b>
 * <pre>
 * Setting piSetting = new Setting(null, "personal-info");
 *
 * Setting fnSetting = new Setting(null, "first-name");
 * piSetting.addChild(fnSetting);
 *
 * Setting fnTextSetting = new Setting(null, "text()");
 * fnTextSetting.setObject(customerObject);
 * fnTextSetting.setMapping(customerFirstNameMapping);
 * fnTextSetting.setValue("Jane");
 * fnSetting.addChild(fnTextSetting);
 *
 * Setting lnSetting = new Setting(null, "last-name");
 * piSetting.addChild(lnSetting);
 *
 * Setting lnTextSetting = new Setting(null, "text()");
 * lnTextSetting.setObject(customerObject);
 * lnTextSetting.setMapping(customerLastNameMapping);
 * lnTextSetting.setValue("Doe");
 * lnSetting.getSequence().add(lnTextSetting);
 * </pre>
 * <pre>
 * &lt;personal-info&gt;
 *      &lt;first-name&gt;Jane&lt;/first-name&gt;
 *      &lt;last-name&gt;Doe&lt;/last-name&gt;
 * &lt;/personal-info&gt;
 * </pre>
 * <b>Example 2</b>
 * <pre>
 * Setting fnpiSetting = new Setting(null, "personal-info");
 *
 * Setting fnSetting = new Setting(null, "first-name");
 * fnpiSetting.addChild(fnSetting);
 *
 * Setting fnTextSetting = new Setting(null, "text()");
 * fnTextSetting.setObject(customerObject);
 * fnTextSetting.setMapping(customerFirstNameMapping);
 * fnTextSetting.setValue("Jane");
 * fnSetting.addChild(fnTextSetting);
 *
 * Setting lnpiSetting = new Setting(null, "personal-info");

 * Setting lastNameSetting = new Setting(null, "last-name");
 * lnpiSetting.addChild(lnSetting);
 *
 * Setting lnTextSetting = new Setting(null, "text()");
 * lnTextSetting.setObject(customerObject);
 * lnTextSetting.setMapping(customerLastNameMapping);
 * lnTextSetting.setValue("Doe");
 * lnSetting.addChild(lnTextSetting);
 * </pre>
 * <pre>
 * &lt;personal-info&gt;
 *      &lt;first-name&gt;Jane&lt;/first-name&gt;
 * &lt;/personal-info&gt;
 * &lt;personal-info&gt;
 *      &lt;last-name&gt;Doe&lt;/last-name&gt;
 * &lt;/personal-info&gt;
 * </pre>
 */
public class Setting {

    private String name;
    private String namespaceURI;
    private Object value;
    private Object object;
    private CoreMapping mapping;
    private Setting parent;
    private List<Setting> children;

    public Setting() {
        super();
    }

    public Setting(String namespaceURI, String name) {
        super();
        this.setNamespaceURI(namespaceURI);
        this.setName(name);
    }

    /**
     * <p>Return the name of the setting.  The name of the setting corresponds
     * to a fragment of an XPath in an object-to-XML mapping.</p>
     * <b>Example</b>
     * <p>For the XPath personal-info/first-name/text() would correspond to 3
     * Setting objects with names "personal-info", "first-name", and "text()"
     * </p>
     */
    public String getName() {
        return name;
    }

    /**
     * <p>Specify the name of the setting.  The name of the setting corresponds
     * to a fragment of an XPath in an object-to-XML mapping.</p>
     * <b>Example</b>
     * <p>For the XPath personal-info/first-name/text() would correspond to 3
     * Setting objects with names "personal-info", "first-name", and "text()"
     * </p>
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return The namespace URI that qualifies the name of the Setting (if there
     * is one).
     */
    public String getNamespaceURI() {
        return namespaceURI;
    }

    /**
     * @param namespaceURI Specify the namespace URI that qualifies the name of the Setting (if
     * there is one).
     */
    public void setNamespaceURI(String namespaceURI) {
        this.namespaceURI = namespaceURI;
    }

    /**
     * @return The value corresponding to this setting.
     */
    public Object getValue() {
        return value;
    }

    /**
     * Set the value on the Setting.  This method will also update the corresponding
     * domain object using the specified mapping.
     * @param value
     */
    public void setValue(Object value) {
        setValue(value, true);
    }

    /**
     * @param value The value to be set on the Setting.
     * @param updateObject This flag indicates if an update is performed
     * on the corresponding domain object using the specified mapping.
     */
    public void setValue(Object value, boolean updateObject) {
        this.value = value;
        if(updateObject) {
            if(null != children) {
                return;
            }
            if(!mapping.isWriteOnly()) {
                mapping.setAttributeValueInObject(object, value);
            }
        }
    }

    /**
     * @param value
     * @param updateObject
     * @param container
     */
    public void addValue(Object value, boolean updateObject, Object container) {
        this.value = value;

        if(updateObject) {
            if(null != children) {
                return;
            }

            CoreContainerPolicy containerPolicy = mapping.getContainerPolicy();
            if(null == container && !(mapping.isWriteOnly())) {
                container = containerPolicy.containerInstance();
                mapping.setAttributeValueInObject(object, container);
            }
            containerPolicy.addInto(value, container, null);
        }
    }

    /**
     * @return The domain object to which this Setting applies.
     */
    public Object getObject() {
        return object;
    }

    /**
     * @param object This is the domain object to which this Setting belongs.
     */
    public void setObject(Object object) {
        this.object = object;
    }

    /**
     * @return The mapping for the domain object that corresponds to this Setting.
     */
    public CoreMapping getMapping() {
        return mapping;
    }

    /**
     * @param mapping The mapping for the domain object that corresponds to this Setting.
     */
    public void setMapping(CoreMapping mapping) {
        this.mapping = mapping;
    }

    /**
     *
     * @param childSetting This setting will be added to the parent.  The parenting
     * information will be updated automatically.  A child must only be added to one parent.
     */
    public void addChild(Setting childSetting) {
        childSetting.setParent(this);
        if(null == children) {
            children = new ArrayList<>();
        }
        children.add(childSetting);
    }

    /**
     * @return The parent Setting or null if this setting has not parent.
     */
    public Setting getParent() {
        return parent;
    }

    /**
     * @param parentSetting The parent Setting or null if this setting has not parent.
     */
    public void setParent(Setting parentSetting) {
        this.parent = parentSetting;
    }

    /**
     * @return The child Settings or null if this setting has no children.
     */
    public List<Setting> getChildren() {
        return children;
    }

    /**
     * @return A copy of the Setting object and its child Setting objects.  The copy
     * contains references to the original object, mapping, and value.
     */
    public Setting copy() {
        Setting copy = new Setting();
        copy.setName(name);
        copy.setNamespaceURI(namespaceURI);
        copy.setObject(object);
        copy.setMapping(mapping);
        copy.setValue(value, false);
        if(null != children) {
            for(int index=0, size=children.size(); index<size; index++) {
                copy.addChild(children.get(index).copy());
            }
        }
        return copy;
    }

    public Setting copy(Object newParent) {
        Setting copy = new Setting();
        copy.setName(name);
        copy.setNamespaceURI(namespaceURI);
        if(getObject() != null){
          copy.setObject(newParent);
        }
        copy.setMapping(mapping);
        copy.setValue(value, false);
        if(null != children) {
            for(int index=0, size=children.size(); index<size; index++) {
                copy.addChild(children.get(index).copy(newParent));
            }
        }
        return copy;
    }

    public Setting copy(Object newParent, Object copyValue) {
        Setting copy = new Setting();
        copy.setName(name);
        copy.setNamespaceURI(namespaceURI);
        if(getObject() != null){
          copy.setObject(newParent);
        }
        copy.setMapping(mapping);
        copy.setValue(copyValue, false);
        if(null != children) {
            for(int index=0, size=children.size(); index<size; index++) {
                copy.addChild(children.get(index).copy(newParent,copyValue));
            }
        }
        return copy;
    }
}
