/****************************************************************
 * 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.james.modules.protocols;

import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;

import javax.inject.Provider;

import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.james.ProtocolConfigurationSanitizer;
import org.apache.james.RunArguments;
import org.apache.james.filesystem.api.FileSystem;
import org.apache.james.imap.api.display.Localizer;
import org.apache.james.imap.api.message.response.StatusResponseFactory;
import org.apache.james.imap.api.process.DefaultMailboxTyper;
import org.apache.james.imap.api.process.ImapProcessor;
import org.apache.james.imap.api.process.MailboxTyper;
import org.apache.james.imap.decode.ImapCommandParser;
import org.apache.james.imap.decode.ImapCommandParserFactory;
import org.apache.james.imap.decode.ImapDecoder;
import org.apache.james.imap.decode.base.AbstractImapCommandParser;
import org.apache.james.imap.decode.main.DefaultImapDecoder;
import org.apache.james.imap.decode.parser.ImapParserFactory;
import org.apache.james.imap.encode.ImapEncoder;
import org.apache.james.imap.encode.ImapResponseEncoder;
import org.apache.james.imap.encode.base.EndImapEncoder;
import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
import org.apache.james.imap.encode.main.DefaultLocalizer;
import org.apache.james.imap.message.response.UnpooledStatusResponseFactory;
import org.apache.james.imap.processor.AuthenticateProcessor;
import org.apache.james.imap.processor.CapabilityImplementingProcessor;
import org.apache.james.imap.processor.CapabilityProcessor;
import org.apache.james.imap.processor.DefaultProcessor;
import org.apache.james.imap.processor.EnableProcessor;
import org.apache.james.imap.processor.PermitEnableCapabilityProcessor;
import org.apache.james.imap.processor.SelectProcessor;
import org.apache.james.imap.processor.base.AbstractProcessor;
import org.apache.james.imap.processor.base.UnknownRequestProcessor;
import org.apache.james.imapserver.netty.IMAPServerFactory;
import org.apache.james.lifecycle.api.ConfigurationSanitizer;
import org.apache.james.metrics.api.GaugeRegistry;
import org.apache.james.metrics.api.MetricFactory;
import org.apache.james.protocols.lib.netty.CertificateReloadable;
import org.apache.james.server.core.configuration.ConfigurationProvider;
import org.apache.james.utils.ClassName;
import org.apache.james.utils.GuiceGenericLoader;
import org.apache.james.utils.GuiceProbe;
import org.apache.james.utils.InitializationOperation;
import org.apache.james.utils.InitilizationOperationBuilder;
import org.apache.james.utils.KeystoreCreator;

import com.github.fge.lambdas.Throwing;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.multibindings.ProvidesIntoSet;

public class IMAPServerModule extends AbstractModule {

    private static Stream<Pair<Class, AbstractProcessor>> asPairStream(AbstractProcessor p) {
        return p.acceptableClasses()
            .stream().map(clazz -> Pair.of(clazz, p));
    }

    @Override
    protected void configure() {
        bind(Localizer.class).to(DefaultLocalizer.class);
        bind(UnpooledStatusResponseFactory.class).in(Scopes.SINGLETON);
        bind(StatusResponseFactory.class).to(UnpooledStatusResponseFactory.class);
        bind(ImapProcessor.class).to(DefaultProcessor.class);

        bind(CapabilityProcessor.class).in(Scopes.SINGLETON);
        bind(AuthenticateProcessor.class).in(Scopes.SINGLETON);
        bind(SelectProcessor.class).in(Scopes.SINGLETON);
        bind(EnableProcessor.class).in(Scopes.SINGLETON);
        bind(MailboxTyper.class).to(DefaultMailboxTyper.class).in(Scopes.SINGLETON);

        Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(ImapGuiceProbe.class);

        Multibinder.newSetBinder(binder(), CertificateReloadable.Factory.class).addBinding().to(IMAPServerFactory.class);
    }

    @Provides
    @Singleton
    IMAPServerFactory provideServerFactory(FileSystem fileSystem, Provider<ImapDecoder> decoder, Provider<ImapEncoder> encoder, Provider<ImapProcessor> processor,
                                        MetricFactory metricFactory, GaugeRegistry gaugeRegistry) {
        return new IMAPServerFactory(fileSystem, decoder, encoder, processor, metricFactory, gaugeRegistry);
    }

    @Provides
    DefaultProcessor provideClassImapProcessors(ImapPackage imapPackage, GuiceGenericLoader loader, StatusResponseFactory statusResponseFactory) {
        ImmutableMap<Class, ImapProcessor> processors = imapPackage.processors()
            .stream()
            .map(Throwing.function(loader::instantiate))
            .map(AbstractProcessor.class::cast)
            .flatMap(IMAPServerModule::asPairStream)
            .collect(ImmutableMap.toImmutableMap(
                Pair::getLeft,
                Pair::getRight));

        Optional<EnableProcessor> enableProcessor = processors.values()
            .stream()
            .filter(EnableProcessor.class::isInstance)
            .map(EnableProcessor.class::cast)
            .findFirst();

        Optional<CapabilityProcessor> capabilityProcessor = processors.values()
            .stream()
            .filter(CapabilityProcessor.class::isInstance)
            .map(CapabilityProcessor.class::cast)
            .findFirst();

        enableProcessor.ifPresent(processor -> configureEnable(processor, processors));
        capabilityProcessor.ifPresent(processor -> configureCapability(processor, processors));

        return new DefaultProcessor(processors, new UnknownRequestProcessor(statusResponseFactory));
    }

    @Provides
    @Singleton
    ImapPackage providePackage(ConfigurationProvider configurationProvider, GuiceGenericLoader loader) {
        try {
            String[] imapPackages = configurationProvider.getConfiguration("imapserver")
                .getStringArray("imapPackages");

            ImmutableList<ImapPackage> packages = Optional.ofNullable(imapPackages)
                .stream()
                .flatMap(Arrays::stream)
                .map(ClassName::new)
                .map(Throwing.function(loader::instantiate))
                .map(ImapPackage.class::cast)
                .collect(ImmutableList.toImmutableList());

            if (packages.isEmpty()) {
                return ImapPackage.DEFAULT;
            }
            return ImapPackage.and(packages);
        } catch (ConfigurationException e) {
            throw new RuntimeException(e);
        }
    }

    @Provides
    ImapDecoder provideImapDecoder(ImapCommandParserFactory imapCommandParserFactory, StatusResponseFactory statusResponseFactory) {
        return new DefaultImapDecoder(statusResponseFactory, imapCommandParserFactory);
    }

    @Provides
    ImapEncoder provideImapEncoder(ImapPackage imapPackage, GuiceGenericLoader loader) {
        Stream<ImapResponseEncoder> encoders = imapPackage.encoders()
            .stream()
            .map(Throwing.function(loader::instantiate))
            .map(ImapResponseEncoder.class::cast);

        return new DefaultImapEncoderFactory.DefaultImapEncoder(encoders, new EndImapEncoder());
    }

    @ProvidesIntoSet
    InitializationOperation configureImap(ConfigurationProvider configurationProvider, IMAPServerFactory imapServerFactory) {
        return InitilizationOperationBuilder
            .forClass(IMAPServerFactory.class)
            .init(() -> {
                imapServerFactory.configure(configurationProvider.getConfiguration("imapserver"));
                imapServerFactory.init();
            });
    }


    private void configureEnable(EnableProcessor enableProcessor, ImmutableMap<Class, ImapProcessor> processorMap) {
        processorMap.values().stream()
            .filter(PermitEnableCapabilityProcessor.class::isInstance)
            .map(PermitEnableCapabilityProcessor.class::cast)
            .forEach(enableProcessor::addProcessor);
    }

    private void configureCapability(CapabilityProcessor capabilityProcessor, ImmutableMap<Class, ImapProcessor> processorMap) {
        processorMap.values().stream()
            .filter(CapabilityImplementingProcessor.class::isInstance)
            .map(CapabilityImplementingProcessor.class::cast)
            .forEach(capabilityProcessor::addProcessor);
    }

    @Provides
    @Singleton
    ImapCommandParserFactory provideImapCommandParserFactory(ImapPackage imapPackage, GuiceGenericLoader loader) {
        ImmutableMap<String, ImapCommandParser> decoders = imapPackage.decoders()
            .stream()
            .map(Throwing.function(loader::instantiate))
            .map(AbstractImapCommandParser.class::cast)
            .collect(ImmutableMap.toImmutableMap(
                parser -> parser.getCommand().getName(),
                Function.identity()));

        return new ImapParserFactory(decoders);
    }

    @ProvidesIntoSet
    ConfigurationSanitizer configurationSanitizer(ConfigurationProvider configurationProvider, KeystoreCreator keystoreCreator,
                                                      FileSystem fileSystem, RunArguments runArguments) {
        return new ProtocolConfigurationSanitizer(configurationProvider, keystoreCreator, fileSystem, runArguments, "imapserver");
    }
}