/*
 * Copyright (c) 2014, 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:
//     Dmitry Kornilov - Initial implementation
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.internal.jpa.rs.metadata.model.ItemLinks;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.LinkV2;
import org.eclipse.persistence.internal.jpa.rs.weaving.PersistenceWeavedRest;
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.features.ItemLinksBuilder;
import org.eclipse.persistence.jpa.rs.util.HrefHelper;
import org.eclipse.persistence.jpa.rs.util.IdHelper;

/**
 * Reference adapter used in JPARS V2. Main purpose of this adapter is retrieving an entity
 * by link when unmarshalling.
 *
 * @param <T> entity class of this adapter
 *
 * @author Dmitry Kornilov
 * @since EclipseLink 2.6.0
 */
public class ReferenceAdapterV2<T extends PersistenceWeavedRest> extends XmlAdapter<T, T> {
    protected PersistenceContext context;

    public ReferenceAdapterV2() {
        super();
    }

    /**
     * Instantiates a new reference adapter.
     *
     * @param context persistent context (mandatory)
     */
    public ReferenceAdapterV2(PersistenceContext context) {
        this.context = context;
    }

    /**
     * Marshal just passes through.
     *
     */
    @Override
    public T marshal(T o) throws Exception {
        if (o == null) {
            return null;
        }

        // Add canonical link
        final String href = HrefHelper.buildEntityHref(context, o.getClass().getSimpleName(), IdHelper.stringifyId(o, o.getClass().getSimpleName(), context));
        if (o._persistence_getLinks() == null) {
            final ItemLinks itemLinks = (new ItemLinksBuilder()).addCanonical(href).build();
            o._persistence_setLinks(itemLinks);
        } else {
            final ItemLinks itemLinks = o._persistence_getLinks();

            final LinkV2 canonicalLink = itemLinks.getCanonicalLink();
            if (canonicalLink == null) {
                o._persistence_getLinks().addLink(new LinkV2(ReservedWords.JPARS_REL_CANONICAL, href));
            }
        }

        return o;
    }

    /**
     * If 'canonical' or 'self' link is present loads entity from the database. Otherwise uses data provided.
     */
    @Override
    public T unmarshal(T o) throws Exception {
        if (o == null) {
            return null;
        }

        if (context == null) {
            return o;
        }

        // Check if links exist and load entity if it does
        if (o._persistence_getLinks() != null && o._persistence_getLinks().getLinks() != null && !o._persistence_getLinks().getLinks().isEmpty()) {
            final ItemLinks itemLinks = o._persistence_getLinks();

            // Use canonical link
            final LinkV2 canonicalLink = itemLinks.getCanonicalLink();
            if (canonicalLink != null && canonicalLink.getHref() != null) {
                return loadEntity(canonicalLink.getHref()) ;
            }

            // Use self link if canonical is not found
            final LinkV2 selfLink = itemLinks.getSelfLink();
            if (selfLink != null && selfLink.getHref() != null) {
                return loadEntity(selfLink.getHref()) ;
            }
        }

        return o;
    }

    private T loadEntity(String href) throws Exception {
        final String uri = href.replace("\\/", "/");
        String entityType = uri.substring(uri.indexOf("/entity/"), uri.lastIndexOf('/'));
        entityType = entityType.substring(entityType.lastIndexOf('/') + 1);
        final String entityId = uri.substring(uri.lastIndexOf('/') + 1);
        final ClassDescriptor descriptor = context.getDescriptor(entityType);
        final Object id = IdHelper.buildId(context, descriptor.getAlias(), entityId);

        return getObjectById(entityType, id);
    }

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