/*
 * Copyright (c) 1998, 2021 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.
     */
    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);
            }
        }
    }

    /**
     */
    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;
    }
}
