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

// 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.
     *
     * @param o
     * @return
     * @throws Exception
     */
    @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);
    }
}
