/*
 * 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.knight.openwebbeans;

import lombok.extern.slf4j.Slf4j;
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.ResourceModel;
import org.apache.openwebbeans.se.CDISeScannerService;
import org.apache.openwebbeans.se.PreScannedCDISeScannerService;
import org.apache.webbeans.component.AbstractProducerBean;
import org.apache.webbeans.component.InjectionTargetBean;
import org.apache.webbeans.component.ManagedBean;
import org.apache.webbeans.config.OpenWebBeansConfiguration;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.conversation.ConversationImpl;
import org.apache.webbeans.corespi.DefaultSingletonService;
import org.apache.webbeans.corespi.se.DefaultScannerService;
import org.apache.webbeans.corespi.se.SimpleApplicationBoundaryService;
import org.apache.webbeans.corespi.se.StandaloneContextsService;
import org.apache.webbeans.inject.impl.InjectionPointImpl;
import org.apache.webbeans.intercept.ApplicationScopedBeanInterceptorHandler;
import org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler;
import org.apache.webbeans.intercept.RequestScopedBeanInterceptorHandler;
import org.apache.webbeans.intercept.SessionScopedBeanInterceptorHandler;
import org.apache.webbeans.lifecycle.StandaloneLifeCycle;
import org.apache.webbeans.logger.WebBeansLoggerFacade;
import org.apache.webbeans.portable.BaseProducerProducer;
import org.apache.webbeans.portable.ProducerFieldProducer;
import org.apache.webbeans.portable.ProducerMethodProducer;
import org.apache.webbeans.portable.events.ExtensionLoader;
import org.apache.webbeans.service.ClassLoaderProxyService;
import org.apache.webbeans.service.DefaultLoaderService;
import org.apache.webbeans.spi.ApplicationBoundaryService;
import org.apache.webbeans.spi.BeanArchiveService;
import org.apache.webbeans.spi.ContainerLifecycle;
import org.apache.webbeans.spi.ContextsService;
import org.apache.webbeans.spi.DefiningClassService;
import org.apache.webbeans.spi.InjectionPointService;
import org.apache.webbeans.spi.JNDIService;
import org.apache.webbeans.spi.LoaderService;
import org.apache.webbeans.spi.ResourceInjectionService;
import org.apache.webbeans.spi.ScannerService;
import org.apache.webbeans.spi.SecurityService;
import org.apache.xbean.finder.filter.Filter;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.Destroyed;
import javax.enterprise.context.Initialized;
import javax.enterprise.context.NormalScope;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.event.ObservesAsync;
import javax.enterprise.event.Reception;
import javax.enterprise.event.TransactionPhase;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.Bean;
import javax.inject.Qualifier;
import javax.interceptor.InterceptorBinding;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static java.util.Collections.singleton;
import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

@Slf4j
public class OpenWebBeansExtension implements ArthurExtension {
    @Override
    public void execute(final Context context) {
        final Properties original = new Properties();
        original.putAll(System.getProperties());
        try (final SeContainer container = configureInitializer(context, SeContainerInitializer.newInstance()).initialize()) {
            final WebBeansContext webBeansContext = WebBeansContext.currentInstance();
            final BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl();
            final Set<Bean<?>> beans = beanManager.getBeans();
            final Predicate<String> classFilter = context.createIncludesExcludes(
                    "extension.openwebbeans.classes.filter.", PredicateType.STARTS_WITH);

            // 1. capture all proxies
            dumpProxies(context, webBeansContext, beans, classFilter);

            // 2. register all classes which will require reflection + proxies
            final String beanClassesList = registerBeansForReflection(context, beans, classFilter);
            getProxies(webBeansContext).keySet().stream().sorted().forEach(name -> {
                final ClassReflectionModel model = new ClassReflectionModel();
                model.setName(name);
                model.setAllDeclaredConstructors(true);
                model.setAllDeclaredFields(true);
                model.setAllDeclaredMethods(true);
                context.register(model);
            });

            // 3. dump owb properties for runtime
            final Properties properties = initProperties(context, webBeansContext.getOpenWebBeansConfiguration(), beanClassesList);

            // 4. register CDI/OWB API which require some reflection
            // 4.1 SPI (interface)
            Stream.of(
                    ScannerService.class, LoaderService.class, BeanArchiveService.class, SecurityService.class,
                    ContainerLifecycle.class, JNDIService.class, ApplicationBoundaryService.class, ContextsService.class,
                    InjectionPointService.class, ResourceInjectionService.class, DefiningClassService.class,
                    Filter.class)
                    .forEach(clazz -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(clazz.getName());
                        model.setAllPublicMethods(true);
                        context.register(model);
                    });
            // 4.2 classes which must be instantiable
            Stream.concat(Stream.of(
                    ClassLoaderProxyService.LoadOnly.class, StandaloneLifeCycle.class, StandaloneContextsService.class,
                    DefaultLoaderService.class, InjectionPointImpl.class, ConversationImpl.class, SimpleApplicationBoundaryService.class,
                    ApplicationScopedBeanInterceptorHandler.class, RequestScopedBeanInterceptorHandler.class,
                    SessionScopedBeanInterceptorHandler.class, NormalScopedBeanInterceptorHandler.class,
                    CDISeScannerService.class, PreScannedCDISeScannerService.class, DefaultScannerService.class),
                    findServices(properties))
                    .distinct()
                    .forEach(clazz -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(clazz.getName());
                        model.setAllDeclaredConstructors(true);
                        context.register(model);
                    });
            // 5 annotations
            final Collection<Class<?>> customAnnotations = Stream.concat(
                    context.findAnnotatedClasses(Qualifier.class).stream(),
                    context.findAnnotatedClasses(NormalScope.class).stream())
                    .collect(toList());
            Stream.concat(Stream.concat(Stream.of(
                    Initialized.class, Destroyed.class, NormalScope.class, ApplicationScoped.class, Default.class,
                    Dependent.class, ConversationScoped.class, RequestScoped.class, Observes.class, ObservesAsync.class,
                    Qualifier.class, InterceptorBinding.class),
                    beanManager.getAdditionalQualifiers().stream()),
                    customAnnotations.stream())
                    .distinct()
                    .map(Class::getName)
                    .sorted()
                    .forEach(clazz -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(clazz);
                        model.setAllDeclaredMethods(true);
                        context.register(model);
                    });
            customAnnotations.stream() // DefaultAnnotation.of
                    .filter(it -> !it.getName().startsWith("javax."))
                    .map(Class::getName)
                    .sorted()
                    .map(it -> {
                        final DynamicProxyModel proxyModel = new DynamicProxyModel();
                        proxyModel.setClasses(singleton(it));
                        return proxyModel;
                    })
                    .forEach(context::register);

            // 6 extensions - normally taken by graalvm service loader but we need a bit more reflection
            final ExtensionLoader extensionLoader = webBeansContext.getExtensionLoader();
            try {
                final Field extensionClasses = ExtensionLoader.class.getDeclaredField("extensionClasses");
                if (!extensionClasses.isAccessible()) {
                    extensionClasses.setAccessible(true);
                }
                final Predicate<String> extensionFilter = context.createPredicate("extension.openwebbeans.extension.excludes", PredicateType.STARTS_WITH)
                        .map(Predicate::negate)
                        .orElseGet(() -> n -> true);
                final Set<Class<?>> classes = (Set<Class<?>>) extensionClasses.get(extensionLoader);
                classes.stream()
                        .filter(it -> extensionFilter.test(it.getName()))
                        .flatMap(this::hierarchy)
                        .distinct()
                        .map(Class::getName)
                        .filter(classFilter)
                        .sorted()
                        .forEach(clazz -> {
                            final ClassReflectionModel model = new ClassReflectionModel();
                            model.setName(clazz);
                            model.setAllDeclaredConstructors(true);
                            model.setAllDeclaredMethods(true);
                            model.setAllDeclaredMethods(true);
                            context.register(model);
                        });
            } catch (final NoSuchFieldException | IllegalAccessException e) {
                throw new IllegalStateException("Incompatible OpenWebBeans version", e);
            }

            // 7. producer types must be reflection friendly
            findProducedClasses(beans)
                    .map(Class::getName)
                    .sorted()
                    .forEach(name -> {
                        final ClassReflectionModel model = new ClassReflectionModel();
                        model.setName(name);
                        model.setAllDeclaredConstructors(true);
                        model.setAllDeclaredFields(true);
                        model.setAllDeclaredMethods(true);
                        context.register(model);
                    });

            // 8. enforce some build time init for annotations and some specific classes
            context.initializeAtBuildTime(
                    Reception.class.getName(),
                    TransactionPhase.class.getName(),
                    DefaultSingletonService.class.getName(),
                    WebBeansLoggerFacade.class.getName());
            try { // openwebbeans-slf4j is an optional module
                final Class<?> logger = context.loadClass("org.apache.openwebbeans.slf4j.Slf4jLogger");
                context.initializeAtBuildTime(logger.getName());
            } catch (final RuntimeException e) {
                // ignore, not there
            }

            // 9. we add the resource bundle + the bundle as resource for some extensions (thank you JUL)
            context.includeResourceBundle("openwebbeans/Messages");
            final ResourceModel resourceModel = new ResourceModel();
            resourceModel.setPattern("openwebbeans/Messages\\.properties");
            context.register(resourceModel);

            // 10. OWB creates proxies on TypeVariable (generics checks) so enable it
            final DynamicProxyModel typeVariableProxyModel = new DynamicProxyModel();
            typeVariableProxyModel.setClasses(singleton(TypeVariable.class.getName()));
            context.register(typeVariableProxyModel);
        } finally {
            System.setProperties(original);
        }
    }

    private Stream<Class<?>> findProducedClasses(final Set<Bean<?>> beans) {
        return beans.stream()
                .filter(it -> AbstractProducerBean.class.isInstance(it) && BaseProducerProducer.class.isInstance(AbstractProducerBean.class.cast(it).getProducer()))
                .flatMap(it -> {
                    final BaseProducerProducer bpp = BaseProducerProducer.class.cast(AbstractProducerBean.class.cast(it).getProducer());
                    final Collection<Type> types = it.getTypes();
                    if (ProducerMethodProducer.class.isInstance(bpp)) {
                        return concat(types, get(bpp, "producerMethod", Method.class).getReturnType());
                    }
                    if (ProducerFieldProducer.class.isInstance(bpp)) {
                        return concat(types, get(bpp, "producerField", AnnotatedField.class).getJavaMember().getType());
                    }
                    return null;
                })
                .filter(Objects::nonNull);
    }

    private Stream<Class<?>> concat(final Collection<Type> types, final Class<?> type) {
        return Stream.concat(Stream.of(type), types.stream().filter(Class.class::isInstance).map(Class.class::cast))
                .distinct() // if types includes type, avoids to do twice the hierarchy
                .flatMap(this::hierarchy)
                .distinct();
    }

    private <T> T get(final BaseProducerProducer p, final String field, final Class<T> type) {
        try {
            final Field declaredField = p.getClass().getDeclaredField(field);
            if (!declaredField.isAccessible()) {
                declaredField.setAccessible(true);
            }
            return type.cast(declaredField.get(p));
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }

    private Stream<? extends Class<?>> findServices(final Properties properties) {
        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        return properties.stringPropertyNames().stream()
                .filter(it -> it.startsWith("org.apache.webbeans.spi.") || it.equals(Filter.class.getName()))
                .map(properties::getProperty)
                .map(it -> {
                    try {
                        return loader.loadClass(it);
                    } catch (final ClassNotFoundException e) {
                        if (it.contains(".")) {
                            log.warn(e.getMessage(), e);
                        } // else can be "false" so just ignore
                        return null;
                    }
                })
                .filter(Objects::nonNull);
    }

    private String registerBeansForReflection(final Context context, final Set<Bean<?>> beans, final Predicate<String> classFilter) {
        final boolean includeClassResources = Boolean.parseBoolean(context.getProperty("extension.openwebbeans.classes.includeAsResources"));
        return beans.stream()
                .filter(ManagedBean.class::isInstance)
                .map(Bean::getBeanClass)
                .flatMap(this::hierarchy)
                .distinct()
                .map(Class::getName)
                .filter(classFilter)
                .sorted()
                .peek(clazz -> {
                    final ClassReflectionModel model = new ClassReflectionModel();
                    model.setName(clazz);
                    model.setAllDeclaredConstructors(true);
                    model.setAllDeclaredMethods(true);
                    model.setAllDeclaredFields(true);
                    context.register(model);

                    if (includeClassResources) {
                        final ResourceModel resourceModel = new ResourceModel();
                        resourceModel.setPattern(Pattern.quote(clazz.replace('.', '/') + ".class"));
                        context.register(resourceModel);
                    }
                })
                .collect(joining(","));
    }

    private void dumpProxies(final Context context, final WebBeansContext webBeansContext, final Set<Bean<?>> beans,
                             final Predicate<String> classFilter) {
        // interceptors/decorators
        beans.stream()
                .filter(InjectionTargetBean.class::isInstance)
                .map(InjectionTargetBean.class::cast)
                .forEach(InjectionTargetBean::defineInterceptorsIfNeeded);
        // normal scope
        beans.stream()
                .filter(it -> webBeansContext.getBeanManagerImpl().isNormalScope(it.getScope()))
                .forEach(webBeansContext.getNormalScopeProxyFactory()::createNormalScopeProxy);

        final Map<String, byte[]> proxies = getProxies(webBeansContext);
        log.debug("Proxies: {}", proxies.keySet());
        if (proxies.isEmpty()) {
            log.info("No proxy found for this application");
        } else {
            proxies.entrySet().stream()
                    .filter(it -> classFilter.test(it.getKey()))
                    .sorted(Map.Entry.comparingByKey())
                    .forEach(e -> {
                        context.registerGeneratedClass(e.getKey(), e.getValue());
                        log.info("Registered proxy '{}'", e.getKey());
                    });
        }
    }

    private Map<String, byte[]> getProxies(final WebBeansContext webBeansContext) {
        return ClassLoaderProxyService.Spy.class.cast(webBeansContext.getService(DefiningClassService.class)).getProxies();
    }

    private Stream<Class<?>> hierarchy(final Class<?> it) {
        return it == null || it == Object.class ?
                Stream.empty() :
                Stream.concat(
                        Stream.concat(Stream.of(it), hierarchy(it.getSuperclass())),
                        Stream.of(it.getInterfaces()).flatMap(this::hierarchy));
    }

    private Properties initProperties(final Context context, final OpenWebBeansConfiguration configuration,
                                      final String beanClassesList) {
        try {
            final Field field = OpenWebBeansConfiguration.class.getDeclaredField("configProperties");
            field.setAccessible(true);

            final Properties properties = Properties.class.cast(field.get(configuration));
            enrichProperties(properties, true);
            if (!Boolean.parseBoolean(context.getProperty("extension.openwebbeans.services.ignoreScannerService"))) {
                properties.put("org.apache.webbeans.spi.ScannerService", "org.apache.openwebbeans.se.PreScannedCDISeScannerService");
            }
            properties.putIfAbsent("org.apache.openwebbeans.se.PreScannedCDISeScannerService.classes", beanClassesList);

            if (!Boolean.getBoolean("extension.openwebbeans.runtime.properties.skipOptimizations")) {
                properties.putIfAbsent("org.apache.webbeans.spi.deployer.skipValidations", "true");
                properties.putIfAbsent("org.apache.webbeans.spi.deployer.skipVetoedOnPackages", "true");
            }

            properties.remove("configuration.ordinal"); // no more needed since it will be unique
            final StringWriter writer = new StringWriter();
            try (final StringWriter w = writer) {
                properties.store(w, "Generated by Geronimo Arthur");
            }

            final Path workDir = Paths.get(requireNonNull(context.getProperty("workingDirectory"), "workingDirectory property"));
            context.addNativeImageOption("-H:OpenWebBeansProperties=" +
                    dump(workDir, "openwebbeans.properties", writer.toString().replaceAll("(?m)^#.*", "")));
            return properties;
        } catch (final Exception e) {
            throw new IllegalStateException("Incompatible OWB version", e);
        }
    }

    private void enrichProperties(final Properties properties, final boolean runtime) {
        properties.setProperty("configuration.ordinal", "10000");

        properties.setProperty("org.apache.webbeans.proxy.useStaticNames", "true");
        properties.setProperty("org.apache.webbeans.proxy.staticNames.useXxHash64", "true");

        properties.setProperty("org.apache.webbeans.spi.DefiningClassService", runtime ?
                "org.apache.webbeans.service.ClassLoaderProxyService$LoadOnly" :
                "org.apache.webbeans.service.ClassLoaderProxyService$Spy");
        properties.setProperty("org.apache.webbeans.spi.ApplicationBoundaryService",
                "org.apache.webbeans.corespi.se.SimpleApplicationBoundaryService");
    }

    private SeContainerInitializer configureInitializer(final Context context, final SeContainerInitializer initializer) {
        final Properties config = new Properties();
        enrichProperties(config, false); // before starting ensure we use a deterministic proxy generation config
        config.stringPropertyNames().forEach(k -> initializer.addProperty(k, config.getProperty(k)));

        if (Boolean.getBoolean(context.getProperty("extension.openwebbeans.container.se.disableDiscovery"))) {
            initializer.disableDiscovery();
        }
        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
        initializer.setClassLoader(loader);
        ofNullable(context.getProperty("extension.openwebbeans.container.se.properties"))
                .ifPresent(props -> {
                    final Properties properties = readProps(props);
                    properties.stringPropertyNames().forEach(k -> initializer.addProperty(k, properties.getProperty(k)));
                });
        ofNullable(context.getProperty("extension.openwebbeans.container.se.services"))
                .ifPresent(props -> {
                    final Properties properties = readProps(props);
                    properties.stringPropertyNames().forEach(k -> {
                        try {
                            initializer.addProperty(k, loader.loadClass(properties.getProperty(k).trim()));
                        } catch (final ClassNotFoundException e) {
                            throw new IllegalArgumentException(e);
                        }
                    });
                });
        ofNullable(context.getProperty("extension.openwebbeans.container.se.classes"))
                .ifPresent(classes -> initializer.addBeanClasses(Stream.of(classes.split(","))
                        .map(String::trim)
                        .filter(it -> !it.isEmpty())
                        .map(it -> {
                            try {
                                return loader.loadClass(it);
                            } catch (final ClassNotFoundException e) {
                                throw new IllegalArgumentException(e);
                            }
                        })
                        .toArray(Class<?>[]::new)));

        return initializer;
    }

    private Properties readProps(final String props) {
        final Properties properties = new Properties();
        try (final StringReader reader = new StringReader(props)) {
            properties.load(reader);
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
        return properties;
    }

    private String dump(final Path workDir, final String name, final String value) {
        if (!java.nio.file.Files.isDirectory(workDir)) {
            try {
                java.nio.file.Files.createDirectories(workDir);
            } catch (final IOException e) {
                throw new IllegalStateException(e);
            }
        }
        final Path out = workDir.resolve(name);
        try {
            Files.write(
                    out, value.getBytes(StandardCharsets.UTF_8),
                    StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
        log.info("Created '{}'", out);
        return out.toAbsolutePath().toString();
    }
}
