/*
 * 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.mappings.nullpolicy;

import java.lang.reflect.Method;

import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.NullCapableValue;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.XPathNode;
import org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecord;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;

/**
 * PUBLIC:
 * <b>Description</b>:
 * This null policy allows for various configurations of isSet behavior to be set.<br>
 * Marshal:<br>
 * The boolean value of the isSet() state of a node will determine whether a node will be written out
 * for a null value.
 * Unmarshal:<br>
 *
 * <p><b>The following instance fields can be set</b>:<ul>
 * <li>isSetMethodName: </li>
 * <li>isSetParameterTypes: </li>
 * <li>isSetParameters: </li>
 * </ul>
 * <p>
 *&nbsp;<b>Usage</b>:<br>
 * <ul>
 * <li> Set to a non-null value<br>IsSet==true, value=value</li>
 * <li> Not set<br>isSet=false, value=null</li>
 * <li> Set to null value<br>isSet=true, value=null</li>
 * <li> Set to default value<br>isSet=false, value=default</li>
 * </ul>
 *
 * @see org.eclipse.persistence.internal.oxm.NullCapableValue
 * @since Oracle TopLink 11<i>g</i> Release 1 (11.1.1)
 */
public class IsSetNullPolicy extends AbstractNullPolicy {
    private static final Class<?>[] PARAMETER_TYPES = {};
    private static final Object[] PARAMETERS = {};
    private String isSetMethodName;
    private Class<?>[] isSetParameterTypes = PARAMETER_TYPES;
    private Object[] isSetParameters = PARAMETERS;
    private Method isSetMethod;

    /**
     * Default Constructor
     * Set the IsSetPerformedForAbsentNode to false to enable the other 2 flags
     * isNullRepresentedByEmptyNode and isNullRepresentedByXsiNil
     */
    public IsSetNullPolicy() {
        super();
        isSetPerformedForAbsentNode = false;
    }

    /**
     * Specific Constructor to set the name for checking the isSet state of the mapping
     */
    public IsSetNullPolicy(String anIsSetMethodName) {
        this();
        setIsSetMethodName(anIsSetMethodName);
    }

    /**
     * Specific Constructor to set both the Marshal enum and the Unmarshal flags.
     */
    public IsSetNullPolicy(String anIsSetMethodName, //
            boolean bIsNullRepresentedByEmptyNode, boolean bIsNullRepresentedByXsiNil, //
            XMLNullRepresentationType aMarshalNullRepresentation) {
        this(anIsSetMethodName);
        setNullRepresentedByEmptyNode(bIsNullRepresentedByEmptyNode);
        setNullRepresentedByXsiNil(bIsNullRepresentedByXsiNil);
        setMarshalNullRepresentation(aMarshalNullRepresentation);
    }

    @Override
    public boolean directMarshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, //
            Object object, CoreSession session, NamespaceResolver namespaceResolver) {
        // Do nothing when the value is not set or we are marshaling as ABSENT_NODE (optional)
        if (!isSet(object)) {
            return false;
        } else {
            return super.directMarshal(xPathFragment, marshalRecord, object, session, namespaceResolver);
        }
    }

    /**
     * INTERNAL
     */
    @Override
    public void directMarshal(Field field, AbstractMarshalRecord record, Object object) {
        if(!isSet(object)) {
            return;
        }
        super.directMarshal(field, record, object);
    }


    /**
     * INTERNAL
     */
    @Override
    public boolean compositeObjectMarshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, //
            Object object, CoreSession session, NamespaceResolver namespaceResolver) {
        // Do nothing when the value is not set or we are marshaling as ABSENT_NODE (optional)
        if (!isSet(object)) {
            return false;
        } else {
            return super.compositeObjectMarshal(xPathFragment, marshalRecord, object, session, namespaceResolver);
        }
    }

    /**
     * INTERNAL
     */
    @Override
    public boolean compositeObjectMarshal(AbstractMarshalRecord record, Object object, Field field, CoreAbstractSession session) {
        if (!isSet(object)) {
            return false;
        } else {
            return super.compositeObjectMarshal(record, object, field, session);
        }
    }

    @Override
    public void xPathNode(XPathNode xPathNode, NullCapableValue nullCapableValue) {
        // isset optional only
        if (!(isNullRepresentedByXsiNil() || marshalNullRepresentation == XMLNullRepresentationType.XSI_NIL)) {
            if (xPathNode.getXPathFragment().isAttribute()) {
                return;
            }
        }

        // get the parent above the text() node
        XPathNode parentNode = xPathNode.getParent();
        parentNode.setNullCapableValue(nullCapableValue);
    }

    /**
     * INTERNAL:
     * Indicates if a null value has been set or not.
     * @return boolean (isSet status)
     */
    private boolean isSet(Object object) {
        try {
            Boolean isSet = PrivilegedAccessHelper.invokeMethod(getIsSetMethod(object.getClass()), object, isSetParameters);
            return isSet;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     */
    public String getIsSetMethodName() {
        return isSetMethodName;
    }

    /**
     *
     */
    public void setIsSetMethodName(String anIsSetMethodName) {
        isSetMethodName = anIsSetMethodName;
    }

    /**
     *
     */
    public Class<?>[] getIsSetParameterTypes() {
        return isSetParameterTypes;
    }

    /**
     *
     */
    public void setIsSetParameterTypes(Class<?>[] parameterTypes) {
        isSetParameterTypes = parameterTypes;
    }

    /**
     *
     */
    public Object[] getIsSetParameters() {
        return isSetParameters;
    }

    /**
     *
     */
    public void setIsSetParameters(Object[] parameters) {
        isSetParameters = parameters;
    }

    private Method getIsSetMethod(Class<?> aClass) throws NoSuchMethodException {
        if(null == isSetMethod) {
             isSetMethod = PrivilegedAccessHelper.getPublicMethod(aClass, getIsSetMethodName(), getIsSetParameterTypes(), false);
        }
        return isSetMethod;
    }

}
