/*
 * Licensed 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.felix.atomos.utils.core;

import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

import org.apache.felix.atomos.utils.api.Context;
import org.apache.felix.atomos.utils.api.FileType;
import org.apache.felix.atomos.utils.api.RegisterServiceCall;
import org.apache.felix.atomos.utils.substrate.api.dynproxy.DynamicProxyConfiguration;
import org.apache.felix.atomos.utils.substrate.api.reflect.ReflectionConfiguration;
import org.apache.felix.atomos.utils.substrate.api.resource.ResourceConfiguration;
import org.apache.felix.atomos.utils.substrate.impl.config.DefaultDynamicProxyConfiguration;
import org.apache.felix.atomos.utils.substrate.impl.config.DefaultReflectionClassConfiguration;
import org.apache.felix.atomos.utils.substrate.impl.config.DefaultReflectionConfiguration;
import org.apache.felix.atomos.utils.substrate.impl.config.DefaultReflectionConstructorConfiguration;
import org.apache.felix.atomos.utils.substrate.impl.config.DefaultReflectionFieldConfiguration;
import org.apache.felix.atomos.utils.substrate.impl.config.DefaultReflectionMethodConfiguration;
import org.apache.felix.atomos.utils.substrate.impl.config.DefaultResourceConfiguration;

public class ContextImpl implements Context
{

    private final Map<Path, FileType> paths = new HashMap<>();

    private final Collection<DefaultReflectionClassConfiguration> reflectConfigs = new ArrayList<>();

    private final List<RegisterServiceCall> registerServiceCalls = new ArrayList<>();

    private final DefaultResourceConfiguration resourceConfig = new DefaultResourceConfiguration();

    private final DefaultDynamicProxyConfiguration dynamicProxyConfigs = new DefaultDynamicProxyConfiguration();

    @Override
    public void addDynamicProxyConfigs(String... items)
    {
        dynamicProxyConfigs.addItem(items);
    }

    @Override
    public void addFile(Path path, FileType type)
    {
        //maybe copy
        paths.put(path, type);
    }

    @Override
    //parameterTypes==null means not Set
    //parameterTypes=={} means no method parameter
    public void addReflecionMethod(String mName, Class<?>[] parameterTypes,
        Class<?> clazz)
    {
        for (Method m : clazz.getDeclaredMethods())
        {
            if (mName.equals(m.getName()))
            {
                if (parameterTypes == null)
                {
                    DefaultReflectionClassConfiguration config = computeIfAbsent(
                        clazz.getName());
                    config.add(new DefaultReflectionMethodConfiguration(mName, null));
                    break;
                }
                else if (Arrays.equals(m.getParameterTypes(), parameterTypes))
                {
                    DefaultReflectionClassConfiguration config = computeIfAbsent(
                        clazz.getName());
                    String[] sParameterTypes = Stream.of(parameterTypes).sequential().map(
                        Class::getName).toArray(String[]::new);
                    config.add(
                        new DefaultReflectionMethodConfiguration(mName, sParameterTypes));
                    break;
                }
            }
        }
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null)
        {
            addReflecionMethod(mName, parameterTypes, superClass);
        }
    }

    @Override
    public void addReflectionClass(String className)
    {
        computeIfAbsent(className);
    }

    @Override
    public void addReflectionConstructor(String bundleActivatorClassName,
        String[] parameterTypeNames)
    {
        computeIfAbsent(bundleActivatorClassName).add(
            new DefaultReflectionConstructorConfiguration(parameterTypeNames));
    }

    @Override
    public void addReflectionConstructorAllPublic(String clazzName)
    {
        computeIfAbsent(clazzName).setAllPublicConstructors(true);
    }

    @Override
    public void addReflectionField(String fName, Class<?> clazz)
    {

        boolean exists = Stream.of(clazz.getDeclaredFields()).anyMatch(
            f -> f.getName().equals(fName));
        if (exists)
        {
            DefaultReflectionClassConfiguration config = computeIfAbsent(clazz.getName());
            config.add(new DefaultReflectionFieldConfiguration(fName));
        }

        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null)
        {
            addReflectionField(fName, superClass);
        }

    }

    @Override
    public void addReflectionFieldsAllPublic(String className)
    {
        computeIfAbsent(className).setAllPublicFields(true);
    }

    @Override
    public void addReflectionMethodsAllPublic(String className)
    {
        computeIfAbsent(className).setAllPublicMethods(true);
    }

    @Override
    public void addRegisterServiceCalls(RegisterServiceCall registerServiceCall)
    {

        registerServiceCalls.add(registerServiceCall);

    }

    @Override
    public void addResourceConfig(ResourceConfiguration resourceConfig)
    {
        this.resourceConfig.addResourcePackage(resourceConfig.getResourcePackages());
        this.resourceConfig.addResourcePattern(resourceConfig.getResourcePatterns());
        this.resourceConfig.addResourceBundle(resourceConfig.getResourceBundles());

    }

    private DefaultReflectionClassConfiguration computeIfAbsent(final String className)
    {
        Optional<DefaultReflectionClassConfiguration> oConfig = reflectConfigs.stream().filter(
            c -> c.getClassName().equals(className)).findFirst();

        DefaultReflectionClassConfiguration rc = null;
        if (oConfig.isPresent())
        {
            rc = oConfig.get();
        }
        else
        {
            rc = new DefaultReflectionClassConfiguration(className);
            reflectConfigs.add(rc);
        }
        return rc;
    }

    @Override
    public DynamicProxyConfiguration getDynamicProxyConfig()
    {
        return dynamicProxyConfigs;
    }

    @Override
    public Stream<Path> getFiles(FileType... fileType)
    {
        return paths.entrySet().stream().filter(
            e -> List.of(fileType).stream().filter(Objects::nonNull).anyMatch(
                t -> t.equals(e.getValue()))).map(Entry::getKey);
    }

    Map<Path, FileType> getPaths()
    {
        return Map.copyOf(paths);
    }

    @Override
    public ReflectionConfiguration getReflectConfig()
    {
        return new DefaultReflectionConfiguration(List.copyOf(reflectConfigs));
    }

    @Override
    public List<RegisterServiceCall> getRegisterServiceCalls()
    {
        return registerServiceCalls;
    }

    @Override
    public ResourceConfiguration getResourceConfig()
    {
        return resourceConfig;
    }

}
