/*
 * 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.sling.models.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.impl.model.ModelClass;
import org.apache.sling.models.spi.ImplementationPicker;
import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Collects alternative adapter implementations that may be defined in a @Model.adapters attribute.
 * If multiple models implement the same adapter they are all collected and can be chose via a ImplementationPicker.
 * Additionally it acts as a cache for model classes without adapter definitions, where adapter and implementation type is the same.
 * The implementation is thread-safe.
 */
final class AdapterImplementations {

    private static final Logger log = LoggerFactory.getLogger(AdapterImplementations.class);

    private final ConcurrentMap<String,ConcurrentNavigableMap<String,ModelClass<?>>> adapterImplementations
            = new ConcurrentHashMap<>();

    private final ConcurrentMap<String,ModelClass<?>> modelClasses
            = new ConcurrentHashMap<>();

    private final ConcurrentMap<String, Class<?>> resourceTypeMappingsForResources = new ConcurrentHashMap<>();
    private final ConcurrentMap<String, Class<?>> resourceTypeMappingsForRequests = new ConcurrentHashMap<>();
    private final ConcurrentMap<Bundle, List<String>> resourceTypeRemovalListsForResources = new ConcurrentHashMap<>();
    private final ConcurrentMap<Bundle, List<String>> resourceTypeRemovalListsForRequests = new ConcurrentHashMap<>();

    private volatile ImplementationPicker[] sortedImplementationPickers = new ImplementationPicker[0];
    private volatile StaticInjectAnnotationProcessorFactory[] sortedStaticInjectAnnotationProcessorFactories = new StaticInjectAnnotationProcessorFactory[0];

    public void setImplementationPickers(Collection<ImplementationPicker> implementationPickers) {
        this.sortedImplementationPickers = implementationPickers.toArray(new ImplementationPicker[implementationPickers.size()]);
    }

    public ImplementationPicker[] getImplementationPickers() {
        return this.sortedImplementationPickers;
    }

    public StaticInjectAnnotationProcessorFactory[] getStaticInjectAnnotationProcessorFactories() {
        return sortedStaticInjectAnnotationProcessorFactories;
    }

    public void setStaticInjectAnnotationProcessorFactories(
            Collection<StaticInjectAnnotationProcessorFactory> factories) {
        this.sortedStaticInjectAnnotationProcessorFactories = factories.toArray(new StaticInjectAnnotationProcessorFactory[factories.size()]);
        updateProcessorFactoriesInModelClasses();
    }

    /**
     * Updates all {@link ModelClass} instances with updates list of static inject annotation processor factories.
     */
    private void updateProcessorFactoriesInModelClasses() {
        Iterator<ModelClass<?>> items = modelClasses.values().iterator();
        updateProcessorFactoriesInModelClasses(items);
        Iterator<ConcurrentNavigableMap<String,ModelClass<?>>> mapItems = adapterImplementations.values().iterator();
        while (mapItems.hasNext()) {
            ConcurrentNavigableMap<String,ModelClass<?>> mapItem = mapItems.next();
            updateProcessorFactoriesInModelClasses(mapItem.values().iterator());
        }
    }
    private void updateProcessorFactoriesInModelClasses(Iterator<ModelClass<?>> items) {
        while (items.hasNext()) {
            ModelClass<?> item = items.next();
            item.updateProcessorFactories(sortedStaticInjectAnnotationProcessorFactories);
        }
    }

    /** Add implementation mapping for the given model class (implementation is the model class itself).
     * Only used for testing purposes. Use {@link #addAll(Class, Class...)} in case you want to register a different implementation.
     * @param modelClasses the model classes to register
     */
    protected void addClassesAsAdapterAndImplementation(Class<?>... modelClasses) {
        for (Class<?> modelClass : modelClasses) {
            addAll(modelClass, modelClass);
        }
    }

    /**
     * Add implementation mapping for the given adapter types.
     * @param implType Implementation type
     * @param adapterTypes Adapter types
     * @result true if adapters were successfully added
     */
    @SuppressWarnings("unchecked")
    boolean addAll(Class<?> implType, Class<?>... adapterTypes) {
        ModelClass<?> modelClass = null;
        try {
            modelClass = new ModelClass(implType, sortedStaticInjectAnnotationProcessorFactories);
        } catch (Exception e) {
            log.warn("Unable to reflect on " + implType.getName(), e);
            return false;
        } catch (NoClassDefFoundError e) {
            log.warn("Unable to reflect on " + implType.getName(), e);
            return false;
        }

        for (Class<?> adapterType : adapterTypes) {
            String key = adapterType.getName();
            if (adapterType == implType) {
                modelClasses.put(key, modelClass);
            } else {
                // although we already use a ConcurrentMap synchronize explicitly because we apply non-atomic operations on it
                synchronized (adapterImplementations) {
                    ConcurrentNavigableMap<String, ModelClass<?>> implementations = adapterImplementations.get(key);
                    if (implementations == null) {
                        // to have a consistent ordering independent of bundle loading use a ConcurrentSkipListMap that sorts by class name
                        implementations = new ConcurrentSkipListMap<>();
                        adapterImplementations.put(key, implementations);
                    }
                    implementations.put(implType.getName(), modelClass);
                }
            }
        }
        return true;
    }

    /**
     * Remove implementation mapping for the given adapter type.
     * @param adapterTypeName Adapter type name
     * @param implTypeName Implementation type name
     */
    public void remove(String adapterTypeName, String implTypeName) {
        String key = adapterTypeName;
        if (StringUtils.equals(adapterTypeName, implTypeName)) {
            modelClasses.remove(key);
        }
        else {
            // although we already use a ConcurrentMap synchronize explicitly because we apply non-atomic operations on it
            synchronized (adapterImplementations) {
                ConcurrentNavigableMap<String,ModelClass<?>> implementations = adapterImplementations.get(key);
                if (implementations != null) {
                    implementations.remove(implTypeName);
                    if (implementations.isEmpty()) {
                        adapterImplementations.remove(key);
                    }
                }
            }
        }
    }

    /**
     * Remove all implementation mappings.
     */
    public void removeAll() {
        modelClasses.clear();
        adapterImplementations.clear();
    }

    /**
     * Lookup the best-matching implementation for the given adapter type by enquiring the {@link ImplementationPicker} services.
     * @param adapterType Adapter type
     * @param adaptable Adaptable for reference
     * @return Implementation type or null if none detected
     */
    @SuppressWarnings("unchecked")
    public <ModelType> ModelClass<ModelType> lookup(Class<ModelType> adapterType, Object adaptable) {
        String key = adapterType.getName();

        // lookup in cache for models without adapter classes
        ModelClass<ModelType> modelClass = (ModelClass<ModelType>)modelClasses.get(key);
        if (modelClass!=null) {
            return modelClass;
        }

        // not found? look in cache with adapter classes
        ConcurrentNavigableMap<String,ModelClass<?>> implementations = adapterImplementations.get(key);
        if (implementations==null || implementations.isEmpty()) {
            return null;
        }
        Collection<ModelClass<?>> implementationsCollection = implementations.values();
        ModelClass<?>[] implementationWrappersArray = implementationsCollection.toArray(new ModelClass<?>[implementationsCollection.size()]);

        // prepare array for implementation picker
        Class<?>[] implementationsArray = new Class<?>[implementationsCollection.size()];
        for (int i=0; i<implementationWrappersArray.length; i++) {
            implementationsArray[i] = implementationWrappersArray[i].getType();
        }

        for (ImplementationPicker picker : this.sortedImplementationPickers) {
            Class<?> implementation = picker.pick(adapterType, implementationsArray, adaptable);
            if (implementation != null) {
                for (int i=0; i<implementationWrappersArray.length; i++) {
                    if (implementation==implementationWrappersArray[i].getType()) {
                        return (ModelClass<ModelType>)implementationWrappersArray[i];
                    }
                }
            }
        }

        return null;
    }

    /**
     * @param adapterType the type to check
     * @return {@code true} in case the given type is a model (may be with a different adapter class)
     */
    @SuppressWarnings("unchecked")
    public <ModelType> boolean isModelClass(Class<ModelType> adapterType) {
        String key = adapterType.getName();

        // lookup in cache for models without adapter classes
        ModelClass<ModelType> modelClass = (ModelClass<ModelType>)modelClasses.get(key);
        if (modelClass!=null) {
            return true;
        }

        // not found? look in cache with adapter classes
        ConcurrentNavigableMap<String,ModelClass<?>> implementations = adapterImplementations.get(key);
        if (implementations==null || implementations.isEmpty()) {
            return false;
        }
        return true;
    }

     public void registerModelToResourceType(final Bundle bundle, final String resourceType, final Class<?> adaptableType, final Class<?> clazz) {
         if (resourceType.startsWith("/")) {
             log.warn("Registering model class {} for adaptable {} with absolute resourceType {}." ,
                     new Object[] { clazz, adaptableType, resourceType });
         }
         ConcurrentMap<String, Class<?>> map;
         ConcurrentMap<Bundle, List<String>> resourceTypeRemovalLists;
         if (adaptableType == Resource.class) {
             map = resourceTypeMappingsForResources;
             resourceTypeRemovalLists = resourceTypeRemovalListsForResources;
         } else if (adaptableType == SlingHttpServletRequest.class) {
             map = resourceTypeMappingsForRequests;
             resourceTypeRemovalLists = resourceTypeRemovalListsForRequests;
         } else {
             log.warn("Found model class {} with resource type {} for adaptable {}. Unsupported type for resourceType binding.",
                     new Object[] { clazz, resourceType, adaptableType });
             return;
         }
         Class<?> existingMapping = map.putIfAbsent(resourceType, clazz);
         if (existingMapping == null) {
             resourceTypeRemovalLists.putIfAbsent(bundle, new CopyOnWriteArrayList<String>());
             resourceTypeRemovalLists.get(bundle).add(resourceType);
         } else {
             log.warn("Skipped registering {} for resourceType {} under adaptable {} because of existing mapping to {}",
                     new Object[] { clazz, resourceType, adaptableType, existingMapping });
         }
     }

     public void removeResourceTypeBindings(final Bundle bundle) {
         List<String> registeredResourceTypes = resourceTypeRemovalListsForResources.remove(bundle);
         if (registeredResourceTypes != null) {
             for (String resourceType : registeredResourceTypes) {
                 resourceTypeMappingsForResources.remove(resourceType);
             }
         }
         registeredResourceTypes = resourceTypeRemovalListsForRequests.remove(bundle);
         if (registeredResourceTypes != null) {
             for (String resourceType : registeredResourceTypes) {
                 resourceTypeMappingsForRequests.remove(resourceType);
             }
         }
     }

     public Class<?> getModelClassForRequest(final SlingHttpServletRequest request) {
         return getModelClassForResource(request.getResource(), resourceTypeMappingsForRequests);
     }

    public Class<?> getModelClassForResource(final Resource resource) {
        return getModelClassForResource(resource, resourceTypeMappingsForResources);
    }

    protected static Class<?> getModelClassForResource(final Resource resource, final Map<String, Class<?>> map) {
        if (resource == null) {
            return null;
        }
        ResourceResolver resolver = resource.getResourceResolver();
        final String originalResourceType = resource.getResourceType();
        Class<?> modelClass = getClassFromResourceTypeMap(originalResourceType, map, resolver);
        if (modelClass != null) {
            return modelClass;
        } else {
            String resourceType = resolver.getParentResourceType(resource);
            while (resourceType != null) {
                modelClass = getClassFromResourceTypeMap(resourceType, map, resolver);
                if (modelClass != null) {
                    return modelClass;
                } else {
                    resourceType = resolver.getParentResourceType(resourceType);
                }
            }
            Resource resourceTypeResource = resolver.getResource(originalResourceType);
            if (resourceTypeResource != null && !resourceTypeResource.getPath().equals(resource.getPath())) {
                return getModelClassForResource(resourceTypeResource, map);
            } else {
                return null;
            }
        }
    }

    private static Class<?> getClassFromResourceTypeMap(final String resourceType, final Map<String, Class<?>> map, final ResourceResolver resolver) {
        if (resourceType == null) {
            return null;
        }
        Class<?> modelClass = map.get(resourceType);
        if (modelClass == null) {
            for (String searchPath : resolver.getSearchPath()) {
                if (resourceType.startsWith("/")) {
                    if (resourceType.startsWith(searchPath)) {
                        modelClass = map.get(resourceType.substring(searchPath.length()));
                        if (modelClass != null) {
                            break;
                        }
                    }
                } else {
                    modelClass = map.get(searchPath + resourceType);
                    if (modelClass != null) {
                        break;
                    }
                }
            }
        }
        return modelClass;
    }

    Map<String, Class<?>> getResourceTypeMappingsForRequests() {
        return Collections.unmodifiableMap(resourceTypeMappingsForRequests);
    }

    Map<String, Class<?>> getResourceTypeMappingsForResources() {
        return Collections.unmodifiableMap(resourceTypeMappingsForResources);
    }
}
