/*
 * 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.geronimo.arthur.impl.nativeimage.generator;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.geronimo.arthur.impl.nativeimage.ArthurNativeImageConfiguration;
import org.apache.geronimo.arthur.spi.ArthurExtension;
import org.apache.geronimo.arthur.spi.model.ClassReflectionModel;
import org.apache.geronimo.arthur.spi.model.DynamicProxyModel;
import org.apache.geronimo.arthur.spi.model.ResourcesModel;

import java.io.IOException;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static java.util.Collections.singletonList;
import static java.util.Comparator.comparing;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toList;

@Slf4j
@RequiredArgsConstructor
public class ConfigurationGenerator implements Runnable {
    private final List<ArthurExtension> extensions;
    private final ArthurNativeImageConfiguration configuration;
    private final Path workingDirectory;
    private final BiConsumer<Object, Writer> jsonSerializer;
    private final Function<Class<? extends Annotation>, Collection<Class<?>>> classFinder;
    private final Function<Class<?>, Collection<Class<?>>> implementationFinder;
    private final Function<Class<? extends Annotation>, Collection<Method>> methodFinder;
    private final Function<Class<? extends Annotation>, Collection<Field>> fieldFinder;
    private final Map<String, String> extensionProperties;

    public ConfigurationGenerator(final Iterable<ArthurExtension> extensions, final ArthurNativeImageConfiguration configuration,
                                  final Path workingDirectory, final BiConsumer<Object, Writer> jsonSerializer,
                                  final Function<Class<? extends Annotation>, Collection<Class<?>>> classFinder,
                                  final Function<Class<? extends Annotation>, Collection<Field>> fieldFinder,
                                  final Function<Class<? extends Annotation>, Collection<Method>> methodFinder,
                                  final Function<Class<?>, Collection<Class<?>>> implementationFinder,
                                  final Map<String, String> extensionProperties) {
        this.extensions = StreamSupport.stream(extensions.spliterator(), false).collect(toList());
        this.configuration = configuration;
        this.workingDirectory = workingDirectory;
        this.jsonSerializer = jsonSerializer;
        this.classFinder = classFinder;
        this.fieldFinder = fieldFinder;
        this.methodFinder = methodFinder;
        this.implementationFinder = implementationFinder;
        this.extensionProperties = extensionProperties;
    }

    @Override
    public void run() {
        // ensure to have a writtable instance (see Context#setProperty(String, String))
        final HashMap<String, String> properties = ofNullable(this.extensionProperties).map(HashMap::new).orElseGet(HashMap::new);
        properties.put("workingDirectory", workingDirectory.toAbsolutePath().toString());

        final DefautContext context = new DefautContext(configuration, classFinder, methodFinder, fieldFinder, implementationFinder, properties);
        for (final ArthurExtension extension : extensions) {
            log.debug("Executing {}", extension);
            context.setModified(false);
            extension.execute(context);
            if (context.isModified()) { // todo: loop while it modifies the context?
                log.info("Extension {} updated build context", extension.getClass().getName());
            }
        }
        try {
            updateConfiguration(context);
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
    }

    private void updateConfiguration(final DefautContext context) throws IOException {
        if (!context.getReflections().isEmpty()) {
            ensureWorkingDirectoryExists();
            final Path json = workingDirectory.resolve("reflection.arthur.json");
            log.info("Creating reflection model '{}'", json);
            try (final Writer writer = Files.newBufferedWriter(
                    json, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
                jsonSerializer.accept(
                        context.getReflections().stream()
                                .collect(groupingBy(ClassReflectionModel::getName))
                                .values().stream()
                                .map(this::merge)
                                .sorted(comparing(ClassReflectionModel::getName))
                                .collect(toList()),
                        writer);
            }
            context.addReflectionConfigFile(json.toAbsolutePath().toString());
        }
        if (!context.getResources().isEmpty() || !context.getBundles().isEmpty()) {
            final ResourcesModel resourcesModel = new ResourcesModel();
            if (!context.getResources().isEmpty()) {
                resourcesModel.setResources(context.getResources());
            }
            if (!context.getBundles().isEmpty()) {
                resourcesModel.setBundles(context.getBundles());
            }
            ensureWorkingDirectoryExists();
            final Path json = workingDirectory.resolve("resources.arthur.json");
            log.info("Creating resources model '{}'", json);
            try (final Writer writer = Files.newBufferedWriter(
                    json, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
                jsonSerializer.accept(resourcesModel, writer);
            }
            context.addResourcesConfigFile(json.toAbsolutePath().toString());
        }
        if (!context.getDynamicProxyModels().isEmpty()) {
            final Set<Collection<String>> proxies = context.getDynamicProxyModels().stream()
                    .map(DynamicProxyModel::getClasses)
                    .collect(toCollection(LinkedHashSet::new));

            ensureWorkingDirectoryExists();
            final Path json = workingDirectory.resolve("dynamicproxies.arthur.json");
            log.info("Creating dynamic proxy model '{}'", json);
            try (final Writer writer = Files.newBufferedWriter(
                    json, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
                jsonSerializer.accept(proxies, writer);
            }
            context.addDynamicProxiesConfigFile(json.toAbsolutePath().toString());
        }
        if (!context.getDynamicClasses().isEmpty()) {
            final Path dynamicClassesDir = workingDirectory.resolve("dynamic_classes");
            context.getDynamicClasses().forEach((name, content) -> {
                final Path target = dynamicClassesDir.resolve(name.replace('.', '/') + ".class");
                if (!Files.exists(target.getParent())) {
                    try {
                        Files.createDirectories(target.getParent());
                    } catch (final IOException e) {
                        throw new IllegalStateException(e);
                    }
                }
                try {
                    Files.write(target, content, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
                } catch (final IOException e) {
                    throw new IllegalStateException(e);
                }
            });
            log.info("Dumped {} generated classes in '{}'", context.getDynamicClasses().size(), dynamicClassesDir);
            if (configuration.getClasspath() == null) {
                configuration.setClasspath(singletonList(dynamicClassesDir.toString()));
            } else {
                configuration.setClasspath(Stream.concat(
                        configuration.getClasspath().stream(),
                        Stream.of(dynamicClassesDir.toString())
                ).distinct().collect(toList()));
            }
        }
    }

    private ClassReflectionModel merge(final List<ClassReflectionModel> classReflectionModels) {
        final Iterator<ClassReflectionModel> modelIterator = classReflectionModels.iterator();
        final ClassReflectionModel model = modelIterator.next();
        while (modelIterator.hasNext()) {
            final ClassReflectionModel next = modelIterator.next();
            if (next.getAllDeclaredClasses()) {
                model.setAllDeclaredClasses(true);
            }
            if (next.getAllDeclaredFields()) {
                model.setAllDeclaredFields(true);
            }
            if (next.getAllDeclaredConstructors()) {
                model.setAllDeclaredConstructors(true);
            }
            if (next.getAllDeclaredMethods()) {
                model.setAllDeclaredMethods(true);
            }
            if (next.getAllPublicMethods()) {
                model.setAllPublicMethods(true);
            }
            if (next.getAllPublicFields()) {
                model.setAllPublicFields(true);
            }
            if (next.getAllPublicConstructors()) {
                model.setAllPublicConstructors(true);
            }
            if (next.getAllPublicClasses()) {
                model.setAllPublicClasses(true);
            }
        }
        return model;
    }

    private void ensureWorkingDirectoryExists() throws IOException {
        if (!Files.exists(workingDirectory)) {
            Files.createDirectories(workingDirectory);
        }
    }
}
