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

import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.caconfig.ConfigurationResolveException;
import org.apache.sling.caconfig.impl.metadata.AnnotationClassParser;
import org.apache.sling.caconfig.spi.metadata.PropertyMetadata;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Maps the property of a resource to a dynamic proxy object implementing
 * the annotation class defining the configuration parameters.
 * Nested configurations with annotation classes referencing other annotation classes are also supported.
 */
final class ConfigurationProxy {

    private ConfigurationProxy() {
        // static methods only
    }

    /**
     * Get dynamic proxy for given resources's properties mapped to given annotation class.
     * @param resource Resource
     * @param clazz Annotation class
     * @param childResolver This is used to resolve nested configuration objects relative to the current configuration resource
     * @return Dynamic proxy object
     */
    @SuppressWarnings("unchecked")
    public @NotNull static <T> T get(@Nullable Resource resource, @NotNull Class<T> clazz, ChildResolver childResolver) {

        // only annotation interface classes are supported
        if (!clazz.isAnnotation()) {
            throw new ConfigurationResolveException("Annotation interface class expected: " + clazz.getName());
        }

        // create dynamic proxy for annotation class accessing underlying resource properties
        // wrap in caching invocation handler so client code can call all methods multiple times
        // without having to worry about performance
        return (T)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz },
                new CachingInvocationHandler(new DynamicProxyInvocationHandler(resource, childResolver)));
    }
    
    /**
     * Resolves nested configurations.
     */
    public static interface ChildResolver {
        <T> T getChild(String configName, Class<T> clazz);
        <T> Collection<T> getChildren(String configName, Class<T> clazz);        
    }

    /**
     * Maps resource properties to annotation class proxy, and support nested configurations.
     */
    static class DynamicProxyInvocationHandler implements InvocationHandler {

        private final Resource resource;
        private final ChildResolver childResolver;

        private DynamicProxyInvocationHandler(Resource resource, ChildResolver childResolver) {
            this.resource = resource;
            this.childResolver = childResolver;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) {
            String propName = AnnotationClassParser.getPropertyName(method.getName());

            // check for nested configuration classes
            Class<?> targetType = method.getReturnType();
            Class<?> componentType = method.getReturnType();
            boolean isArray = targetType.isArray();
            if (isArray) {
                componentType = targetType.getComponentType();
            }
            if (componentType.isAnnotation()) {
                if (isArray) {
                    Collection<?> listItems = childResolver.getChildren(propName, componentType);
                    return listItems.toArray((Object[])Array.newInstance(componentType, listItems.size()));
                }
                else {
                    return childResolver.getChild(propName, componentType);
                }
            }

            // validate type
            if (!isValidType(componentType)) {
                throw new ConfigurationResolveException("Unsupported type " + componentType.getName()
                  + " in " + method.getDeclaringClass() + "#" + method.getName());
            }

            // detect default value
            Object defaultValue = method.getDefaultValue();
            if (defaultValue == null) {
                if (isArray) {
                    defaultValue = Array.newInstance(componentType, 0);
                }
                else if (targetType.isPrimitive()) {
                    // get default value for primitive data type (use hack via array)
                    defaultValue = Array.get(Array.newInstance(targetType, 1), 0);
                }
            }

            // get value from valuemap with given type/default value
            ValueMap props = ResourceUtil.getValueMap(resource);
            Object value;
            if (defaultValue != null) {
                value = props.get(propName, defaultValue);
            }
            else {
                value = props.get(propName, targetType);
            }
            return value;

        }

        /**
         * Ensures the given type is support for reading configuration parameters.
         * @param type Type
         * @return true if type is supported
         */
        private boolean isValidType(Class<?> type) {
            return PropertyMetadata.SUPPORTED_TYPES.contains(type);
        }
        
    }

    /**
     * Invocation handler that caches all results for each method name, and returns
     * the result from cache on next invocation.
     */
    static class CachingInvocationHandler implements InvocationHandler {

        private final InvocationHandler delegate;
        private final Map<String, Object> results = new HashMap<>();
        private static final Object NULL_OBJECT = new Object();

        public CachingInvocationHandler(InvocationHandler delegate) {
            this.delegate = delegate;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String key = method.getName();
            Object result = results.get(key);
            if (result == null) {
                result = delegate.invoke(proxy, method, args);
                if (result == null) {
                    result = NULL_OBJECT;
                }
                results.put(key,  result);
            }
            if (result == NULL_OBJECT) {
                return null;
            }
            else {
                return result;
            }
        }

    }

}
