/*
 * 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 java.util.ArrayList;
import java.util.Collection;

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

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.CollectionWrapper;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.LinkV2;
import org.eclipse.persistence.internal.jpa.rs.weaving.PersistenceWeavedRest;
import org.eclipse.persistence.internal.sessions.AbstractSession;
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.CollectionProxy;
import org.eclipse.persistence.jpa.rs.util.IdHelper;
import org.eclipse.persistence.mappings.DatabaseMapping;

/**
 * Collections adapter used in JPARS V2. Collections are wrapped into CollectionWrapper which has 'links'.
 * @see CollectionWrapper
 *
 * @param <T> list generac type
 *
 * @author Dmitry Kornilov
 * @since EclipseLink 2.6.0
 */
public class RestCollectionAdapter<T extends PersistenceWeavedRest> extends XmlAdapter<CollectionWrapper<T>, Collection<T>> {
    protected PersistenceContext context;

    public RestCollectionAdapter() {
        super();
    }

    /**
     * Instantiates a new RestCollectionAdapter.
     *
     * @param context persistent context
     */
    public RestCollectionAdapter(PersistenceContext context) {
        this.context = context;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Collection<T> unmarshal(CollectionWrapper<T> v) throws Exception {
        if (v == null) {
            return null;
        }

        final Collection<T> result = new ArrayList<>();

        // Check if links exist and items from there if it does
        if (v.getLinks() != null && !v.getLinks().isEmpty()) {
            for (final LinkV2 link : v.getLinks()) {
                if (link.getRel().equals(ReservedWords.JPARS_REL_SELF) && link.getHref() != null) {
                    return loadItems(link.getHref());
                }
            }
        }

        if (v.getItems() != null) {
            // Process each item (load from href, etc.)
            final ReferenceAdapterV2<T> referenceAdapter = new ReferenceAdapterV2<>(context);
            for (T item : v.getItems()) {
                if (context != null) {
                    result.add(referenceAdapter.unmarshal(item));
                } else {
                    result.add(item);
                }
            }
        }
        return result;
    }

    @Override
    public CollectionWrapper<T> marshal(Collection<T> v) throws Exception {
        if (v == null || v.isEmpty()) {
            return null;
        }

        final CollectionWrapper<T> result = new CollectionWrapper<>();

        // Currently it returns only links. It will return items when 'expand'
        // feature will be implemented.
        //result.setItems(v);

        // Read links from the RestCollection wrapper
        if (v instanceof CollectionProxy) {
            CollectionProxy restCollection = (CollectionProxy)v;
            result.setLinks(restCollection.getLinks());
        }

        return result;
    }

    private Collection loadItems(String href) throws Exception {
        String uri = href.replace("\\/", "/");
        uri = uri.substring(uri.indexOf("entity/"));
        uri = uri.substring(uri.indexOf('/') + 1);

        final String[] uriItems = uri.split("/");
        final String entityType = uriItems[0];
        final String entityId = uriItems[1];
        final String attributeName = uriItems[2];

        final ClassDescriptor descriptor = context.getDescriptor(entityType);
        final Object id = IdHelper.buildId(context, descriptor.getAlias(), entityId);

        final T entity = getObjectById(entityType, id);
        final DatabaseMapping attributeMapping = descriptor.getMappingForAttributeName(attributeName);
        if ((attributeMapping == null) || (entity == null)) {
            throw JPARSException.databaseMappingCouldNotBeFoundForEntityAttribute(attributeName, entityType, entityId, null);
        }

        return (Collection) attributeMapping.getRealAttributeValueFromAttribute(attributeMapping.getAttributeValueFromObject(entity), entity, (AbstractSession)context.getServerSession());
    }

    @SuppressWarnings("unchecked")
    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);
    }
}
