/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.persistence.meta;

import static javax.persistence.metamodel.Type.PersistenceType.BASIC;
import static javax.persistence.metamodel.Type.PersistenceType.EMBEDDABLE;
import static javax.persistence.metamodel.Type.PersistenceType.ENTITY;
import static javax.persistence.metamodel.Type.PersistenceType.MAPPED_SUPERCLASS;

import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.security.AccessController;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MappedSuperclassType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.PluralAttribute.CollectionType;
import javax.persistence.metamodel.StaticMetamodel;
import javax.persistence.metamodel.Type;
import javax.persistence.metamodel.Type.PersistenceType;

import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.kernel.QueryContext;
import org.apache.openjpa.kernel.exps.AggregateListener;
import org.apache.openjpa.kernel.exps.FilterListener;
import org.apache.openjpa.kernel.exps.Resolver;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.meta.Members.Member;
import org.apache.openjpa.util.InternalException;

/**
 * Adapts JPA Metamodel to OpenJPA meta-data repository.
 *
 * @author Pinaki Poddar
 *
 */
public class MetamodelImpl implements Metamodel, Resolver {
    private final MetaDataRepository repos;
    private Map<Class<?>, Type<?>> _basics = new HashMap<>();
    private Map<Class<?>, EntityType<?>> _entities = new HashMap<>();
    private Set<EntityType<?>> _entitiesOnlySet = null;
    private Map<Class<?>, EmbeddableType<?>> _embeddables = new HashMap<>();
    private Map<Class<?>, MappedSuperclassType<?>> _mappedsupers = new HashMap<>();
    private Map<Class<?>, Types.PseudoEntity<?>> _pseudos = new HashMap<>();

    private static Localizer _loc = Localizer.forPackage(MetamodelImpl.class);

    /**
     * Constructs a model with the current content of the supplied non-null repository.
     *
     */
    public MetamodelImpl(MetaDataRepository repos) {
        this.repos = repos;
        Collection<Class<?>> classes = repos.loadPersistentTypes(true, null);
        for (Class<?> cls : classes) {
            if (repos.skipMetadata(cls)) { // AttributeConverters, enums etc....
                continue;
            }

        	ClassMetaData meta = repos.getMetaData(cls, null, true);
            PersistenceType type = getPersistenceType(meta);
            switch (type) {
            case ENTITY:
                find(cls, _entities, ENTITY, false);
                if (meta.isEmbeddable())
                    find(cls, _embeddables, EMBEDDABLE, false);
                break;
            case EMBEDDABLE:
                find(cls, _embeddables, EMBEDDABLE, false);
                break;
            case MAPPED_SUPERCLASS:
                find(cls, _mappedsupers, MAPPED_SUPERCLASS, false);
                break;
            default:
            }
        }
    }

    public MetaDataRepository getRepository() {
        return repos;
    }

    /**
     *  Return the metamodel embeddable type representing the embeddable class.
     *
     *  @param cls  the type of the represented embeddable class
     *  @return the metamodel embeddable type
     *  @throws IllegalArgumentException if not an embeddable class
     */
    @Override
    public <X> EmbeddableType<X> embeddable(Class<X> clazz) {
        return (EmbeddableType<X>)find(clazz, _embeddables, EMBEDDABLE, false);
    }

    /**
     *  Return the metamodel entity type representing the entity.
     *  @param cls  the type of the represented entity
     *  @return the metamodel entity type
     *  @throws IllegalArgumentException if not an entity
     */
    @Override
    public <X> EntityType<X> entity(Class<X> clazz) {
        return (EntityType<X>) find(clazz, _entities, ENTITY, false);
    }

    public <X> EntityType<X> entityImpl(Class<X> clazz) {
        return (EntityType<X>) find(clazz, _entities, ENTITY, true);
    }

    /*
     * Return the most up-to-date entity only set in the current meta model.
     */
    private Collection<EntityType<?>> getEntityValuesOnly() {
        if (_entitiesOnlySet == null) {
            _entitiesOnlySet = new HashSet<>();
            for (Class<?> cls : _entities.keySet()) {
                // if key indicates it is a embeddable, do not add to the _entitiesOnlySet.
                if (!_embeddables.containsKey(cls)) {
                    _entitiesOnlySet.add(_entities.get(cls));
                }
            }
        }
        return _entitiesOnlySet;
    }

    /**
     * Return the metamodel embeddable types.
     * @return the metamodel embeddable types
     */
    @Override
    public Set<EmbeddableType<?>> getEmbeddables() {
        return unmodifiableSet(_embeddables.values());
    }

    /**
     * Return the metamodel entity types.
     * @return the metamodel entity types
     */
    @Override
    public Set<EntityType<?>> getEntities() {
        return unmodifiableSet(getEntityValuesOnly());
    }

    /**
     *  Return the metamodel managed types.
     *  @return the metamodel managed types
     */
    @Override
    public Set<ManagedType<?>> getManagedTypes() {
        Set<ManagedType<?>> result = new HashSet<>();
        result.addAll(getEntityValuesOnly());
        result.addAll(_embeddables.values());
        result.addAll(_mappedsupers.values());
        return result;
    }

    /**
     *  Return the metamodel managed type representing the
     *  entity, mapped superclass, or embeddable class.
     *  @param cls  the type of the represented managed class
     *  @return the metamodel managed type
     *  @throws IllegalArgumentException if not a managed class
     */
    @Override
    public <X> ManagedType<X> managedType(Class<X> clazz) {
        if (_embeddables.containsKey(clazz))
            return (EmbeddableType<X>) _embeddables.get(clazz);
        if (_entities.containsKey(clazz))
            return (EntityType<X>) _entities.get(clazz);
        if (_mappedsupers.containsKey(clazz))
            return (MappedSuperclassType<X>) _mappedsupers.get(clazz);
        throw new IllegalArgumentException(_loc.get("type-not-managed", clazz)
            .getMessage());
    }

    /**
     *  Return the type representing the basic, entity, mapped superclass, or embeddable class.
     *  This method differs from {@linkplain #type(Class)} as it also creates a basic or pesudo
     *  type for the given class argument if not already available in this receiver.
     *
     *  @param cls  the type of the represented managed class
     *  @return the metamodel managed type
     *  @throws IllegalArgumentException if not a managed class
     */
    public <X> Type<X> getType(Class<X> cls) {
        try {
            return managedType(cls);
        } catch (IllegalArgumentException ex) {
            if (_basics.containsKey(cls))
                return (Type<X>)_basics.get(cls);
            if (_pseudos.containsKey(cls))
                return (Type<X>)_pseudos.get(cls);
            if (java.util.Map.class.isAssignableFrom(cls)) {
                Types.PseudoEntity<X> pseudo = new Types.PseudoEntity(cls, this);
                _pseudos.put(cls, new Types.PseudoEntity(cls, this));
                return pseudo;
            } else {
                Type<X> basic = new Types.Basic<>(cls);
                _basics.put(cls, basic);
                return basic;
            }
        }
    }

    public static PersistenceType getPersistenceType(ClassMetaData meta) {
        if (meta == null)
            return BASIC;
        if (meta.isAbstract())
            return MAPPED_SUPERCLASS;
        if (meta.isEmbeddable())
            return EMBEDDABLE;
        return ENTITY;
    }

    /**
     * Looks up the given container for the managed type representing the given Java class.
     * The managed type may become instantiated as a side-effect.
     */
    private <V extends ManagedType<?>> V find(Class<?> cls, Map<Class<?>,V> container,
            PersistenceType expected, boolean implFind) {
        if (container.containsKey(cls)) {
            if (implFind || expected != ENTITY || !_embeddables.containsKey(cls)) {
                return container.get(cls);
            }
        }
        ClassMetaData meta = repos.getMetaData(cls, null, false);
        if (meta != null) {
            instantiate(cls, meta, container, expected);
        }
        return container.get(cls);
    }

    /**
     * Instantiate
     * @param <X>
     * @param <V>
     * @param cls
     * @param container
     * @param expected
     */
    private <X,V extends ManagedType<?>> void instantiate(Class<X> cls, ClassMetaData meta,
            Map<Class<?>,V> container, PersistenceType expected) {
        PersistenceType actual = getPersistenceType(meta);
        if (actual != expected) {
            if (!meta.isEmbeddable() || actual != PersistenceType.ENTITY ||
                expected != PersistenceType.EMBEDDABLE)
                throw new IllegalArgumentException( _loc.get("type-wrong-category",
                    cls, actual, expected).getMessage());
        }
        switch (actual) {
        case EMBEDDABLE:
            Types.Embeddable<X> embedded = new Types.Embeddable<>(meta, this);
            _embeddables.put(cls, embedded);
            populate(embedded);
            // no break : embeddables are stored as both entity and embeddable containers
        case ENTITY:
        	Types.Entity<X> entity = new Types.Entity<>(meta, this);
            _entities.put(cls, entity);
            _entitiesOnlySet = null;
            populate(entity);
            break;
        case MAPPED_SUPERCLASS:
            Types.MappedSuper<X> mapped = new Types.MappedSuper<>(meta, this);
            _mappedsupers.put(cls, mapped);
            populate(mapped);
            break;
        default:
            throw new InternalException(cls.getName());
        }
    }

    public <T> Set<T> unmodifiableSet(Collection<T> coll) {
        HashSet<T> result = new HashSet<>();
        for (T t : coll)
            result.add(t);
        return result;
    }

    static CollectionType categorizeCollection(Class<?> cls) {
        if (Set.class.isAssignableFrom(cls))
            return CollectionType.SET;
        if (List.class.isAssignableFrom(cls))
            return CollectionType.LIST;
        if (Collection.class.isAssignableFrom(cls))
            return CollectionType.COLLECTION;
        if (Map.class.isAssignableFrom(cls))
            return CollectionType.MAP;

        throw new InternalException(cls.getName() + " not a collection");
    }

    /**
     * Populate the static fields of the canonical type.
     */
    public <X> void populate(AbstractManagedType<X> type) {
        Class<X> cls = type.getJavaType();
        Class<?> mcls = repos.getMetaModel(cls, true);
        if (mcls == null)
            return;
        StaticMetamodel anno = mcls.getAnnotation(StaticMetamodel.class);
        if (anno == null)
            throw new IllegalArgumentException(_loc.get("meta-class-no-anno",
                    mcls.getName(), cls.getName(), StaticMetamodel.class.getName()).getMessage());

        if (cls != anno.value()) {
            throw new IllegalStateException(_loc.get("meta-class-mismatch",
                    mcls.getName(), cls.getName(), anno.value()).getMessage());
        }

        ParameterizedType mfType = null;
        Attribute<? super X, ?> f = null;
        Field[] mfields = AccessController.doPrivileged(J2DoPrivHelper.getDeclaredFieldsAction(mcls));
        for (Field mf : mfields) {
            try {
                mfType = getParameterizedType(mf); // metamodel type
                if (mfType == null) {
                    continue;
                }
                f = type.getAttribute(mf.getName()); // persistent type

                // populate the static field with persistent type information
                mf.set(null, f);
            } catch (Exception e) {
                throw new RuntimeException(_loc.get("meta-field-mismatch",
                        new Object[] { mf.getName(), mcls.getName(), toTypeName(mfType), f.getJavaType().toString() })
                        .getMessage(), e);
            }
        }
    }

    /**
     * Gets the parameterized type of the given field after validating.
     *
     * @return the field's type as a parameterized type. If the field
     * is not parameterized type (that can happen for non-canonical
     * metamodel or weaving process introducing synthetic fields),
     * returns null.
     */
    ParameterizedType getParameterizedType(Field mf) {
        java.lang.reflect.Type t = mf.getGenericType();
        if (t instanceof ParameterizedType == false) {
        	repos.getLog().warn(_loc.get("meta-field-not-param",
            mf.getDeclaringClass(), mf.getName(), toTypeName(t)).getMessage());
        	return null;
        }
        ParameterizedType mfType = (ParameterizedType)t;
        java.lang.reflect.Type[] args = mfType.getActualTypeArguments();
        if (args.length < 2) {
            throw new IllegalStateException(_loc.get("meta-field-less-param",
            mf.getDeclaringClass(), mf.getName(), toTypeName(t)).getMessage());
        }

        return mfType;
    }

    /**
     * Pretty prints a Type.
     */
    String toTypeName(java.lang.reflect.Type type) {
        if (type instanceof GenericArrayType) {
            return toTypeName(((GenericArrayType)type).
                getGenericComponentType())+"[]";
        }
        if (type instanceof ParameterizedType == false) {
            Class<?> cls = (Class<?>)type;
            return cls.getName();
        }
        ParameterizedType pType = (ParameterizedType)type;
        java.lang.reflect.Type[] args = pType.getActualTypeArguments();
        StringBuilder tmp = new StringBuilder(pType.getRawType().toString());
        for (int i = 0; i < args.length; i++) {
            tmp.append((i == 0) ? '<' : ',');
            tmp.append(toTypeName(args[i]));
            if (i == args.length-1) tmp.append('>');
        }
        return tmp.toString();
    }

    /**
     * Validates the given field of the meta class matches the given
     * FieldMetaData and
     * @param <X>
     * @param <Y>
     * @param mField
     * @param member
     */
    void validate(Field metaField, FieldMetaData fmd) {

    }

    <X,Y> void validate(Field mField, Member<X, Y> member) {
        if (!ParameterizedType.class.isInstance(mField.getGenericType())) {
            throw new IllegalArgumentException(_loc.get("meta-bad-field",
                mField).getMessage());
        }
        ParameterizedType mfType = (ParameterizedType)mField.getGenericType();
        java.lang.reflect.Type[] args = mfType.getActualTypeArguments();
        java.lang.reflect.Type owner = args[0];
        if (member.getDeclaringType().getJavaType() != owner)
            throw new IllegalArgumentException(_loc.get("meta-bad-field-owner",
                    mField, owner).getMessage());
    }

    @Override
    public Class classForName(String name, String[] imports) {
        throw new UnsupportedOperationException();
    }

    @Override
    public AggregateListener getAggregateListener(String tag) {
        throw new UnsupportedOperationException();
    }

    @Override
    public OpenJPAConfiguration getConfiguration() {
        return repos.getConfiguration();
    }

    @Override
    public FilterListener getFilterListener(String tag) {
        throw new UnsupportedOperationException();
    }

    @Override
    public QueryContext getQueryContext() {
        throw new UnsupportedOperationException();
    }
}
