/*
 * 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:
// bdoughan - August 5/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.internal.jaxb;

import jakarta.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
import org.eclipse.persistence.sessions.Session;

/**
 * Convert between instances of XMLRoot and JAXBElement
 */
public class JAXBElementRootConverter implements XMLConverter {

    private Class<?> declaredType;
    private XMLConverter nestedConverter;

    public JAXBElementRootConverter(Class<?> declaredType) {
        this.declaredType = declaredType;
    }

    public Converter getNestedConverter() {
        return nestedConverter;
    }

    public void setNestedConverter(XMLConverter nestedConverter) {
        this.nestedConverter = nestedConverter;
    }

    @Override
    public void initialize(DatabaseMapping mapping, Session session) {
        if(null != nestedConverter) {
            nestedConverter.initialize(mapping, session);
        }
    }

    @Override
    public Object convertDataValueToObjectValue(Object dataValue, Session session) {
        return this.convertDataValueToObjectValue(dataValue, session, null);
    }

    @Override
    public Object convertDataValueToObjectValue(Object dataValue, Session session, XMLUnmarshaller unmarshaller) {
        if(null != nestedConverter) {
            dataValue = nestedConverter.convertDataValueToObjectValue(dataValue, session, unmarshaller);
        }
        if(dataValue instanceof JAXBElement) {
            return dataValue;
        } else if(dataValue instanceof Root) {
            Root root = (Root)dataValue;
            QName name = new QName(root.getNamespaceURI(), root.getLocalName());
            dataValue = root.getObject();
            if(null == dataValue) {
                return createJAXBElement(name, Object.class, null);
            }else{
                return createJAXBElement(name, declaredType, dataValue);
            }
        }
        return dataValue;
    }

    @Override
    public Object convertObjectValueToDataValue(Object objectValue, Session session) {
        return this.convertObjectValueToDataValue(objectValue, session, null);
    }

    @Override
    public Object convertObjectValueToDataValue(Object objectValue, Session session, XMLMarshaller marshaller) {
        if(null != nestedConverter) {
            objectValue = nestedConverter.convertObjectValueToDataValue(objectValue, session, marshaller);
        }

        if(objectValue instanceof JAXBElement) {
            ClassDescriptor desc = session.getDescriptor(objectValue);
            if(desc == null || objectValue instanceof WrappedValue){
                JAXBElement element = (JAXBElement) objectValue;
                Root root = new XMLRoot();
                root.setLocalName(element.getName().getLocalPart());
                root.setNamespaceURI(element.getName().getNamespaceURI());
                root.setObject(element.getValue());
                root.setDeclaredType(element.getDeclaredType());
                root.setNil(element.isNil());
                return root;
            }
        }
        return objectValue;
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    private JAXBElement createJAXBElement(QName qname, Class<?> theClass, Object value){
        if(value != null && value instanceof JAXBElement){
            return (JAXBElement)value;
        }
        if(CoreClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(theClass)){
            theClass = CoreClassConstants.XML_GREGORIAN_CALENDAR;
        }else if(CoreClassConstants.DURATION.isAssignableFrom(theClass)){
            theClass = CoreClassConstants.DURATION;
        }
        return new JAXBElement(qname, theClass, value);
    }

}
