/*
 * Copyright (c) 2011, 2020 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
 */

package org.eclipse.persistence.jpa.rs.util.xmladapters;

import jakarta.xml.bind.annotation.adapters.XmlAdapter;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.FetchGroupManager;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.Link;
import org.eclipse.persistence.internal.jpa.rs.weaving.PersistenceWeavedRest;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.jpa.rs.PersistenceContext;
import org.eclipse.persistence.jpa.rs.ReservedWords;
import org.eclipse.persistence.jpa.rs.exceptions.JPARSException;
import org.eclipse.persistence.jpa.rs.util.IdHelper;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;

public class ReferenceAdapter<T extends PersistenceWeavedRest> extends XmlAdapter<Object, Object> {
    private String baseURI = null;
    private PersistenceContext context = null;

    /**
     * Instantiates a new reference adapter.
     */
    public ReferenceAdapter() {
        super();
    }

    /**
     * Instantiates a new reference adapter.
     *
     * @param baseURI
     *            the base uri
     * @param context
     *            the context
     */
    public ReferenceAdapter(String baseURI, PersistenceContext context) {
        this.baseURI = baseURI;
        this.context = context;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * jakarta.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    @Override
    public Link marshal(Object o) throws Exception {
        if (o == null) {
            return null;
        }

        ClassDescriptor descriptor = context.getJAXBDescriptorForClass(o.getClass());
        T t = (T) descriptor.getObjectBuilder().buildNewInstance();
        Link link = new Link();
        link.setMethod("GET");
        link.setRel(ReservedWords.JPARS_REL_SELF);
        String id = IdHelper.stringifyId(o, descriptor.getAlias(), context);
        String version = context.getVersion();
        if (version != null) {
            link.setHref(baseURI + version + "/" + context.getName() + "/entity/" + descriptor.getAlias() + "/" + id);
        } else {
            link.setHref(baseURI + context.getName() + "/entity/" + descriptor.getAlias() + "/" + id);
        }
        descriptor.getMappingForAttributeName("_persistence_href").setAttributeValueInObject(t, link);
        return link;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * jakarta.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    @Override
    public T unmarshal(Object object) throws Exception {
        if (object == null) {
            return null;
        }

        PersistenceWeavedRest persistenceWeavedRest = null;
        Link link;

        if (object instanceof PersistenceWeavedRest) {
            persistenceWeavedRest = (PersistenceWeavedRest) object;
            link = persistenceWeavedRest._persistence_getHref();
        } else if (object instanceof Link) {
            link = (Link) object;
        } else {
            return null;
        }

        if (null == link || link.getHref() == null) {
            if (persistenceWeavedRest != null) {
                ClassDescriptor descriptor = context.getJAXBDescriptorForClass(persistenceWeavedRest.getClass());
                if (persistenceWeavedRest instanceof FetchGroupTracker && JpaHelper.getDatabaseSession(context.getEmf()).doesObjectExist(persistenceWeavedRest)) {
                    if (context.doesExist(null, persistenceWeavedRest)) {
                        FetchGroup fetchGroup = new FetchGroup();
                        for (DatabaseMapping mapping : descriptor.getMappings()) {
                            if (!(mapping instanceof XMLInverseReferenceMapping)) {
                                fetchGroup.addAttribute(mapping.getAttributeName());
                            }
                        }
                        (new FetchGroupManager()).setObjectFetchGroup(persistenceWeavedRest, fetchGroup, null);
                    }
                }
                return (T) persistenceWeavedRest;
            }
        }

        // Construct object from the href
        if ((link != null) && (link.getHref() != null)) {
            String uri = link.getHref().replace("\\/", "/");
            String entityType = uri.substring(uri.indexOf("/entity/"), uri.lastIndexOf('/'));
            entityType = entityType.substring(entityType.lastIndexOf('/') + 1);
            String entityId = uri.substring(uri.lastIndexOf('/') + 1);
            ClassDescriptor descriptor = context.getDescriptor(entityType);
            Object id = IdHelper.buildId(context, descriptor.getAlias(), entityId);

            T foundEntity = (T) getObjectById(entityType, id);
            return foundEntity;
        }

        return null;
    }

    private Object getObjectById(String entityType, Object id) throws Exception {
        Object entity = context.find(null, entityType, id, null);
        if (entity != null) {
            return entity;
        }
        // It is an error if the object referred by a link doesn't exist, so throw exception
        throw JPARSException.objectReferredByLinkDoesNotExist(entityType, id);
    }
}
