/**
 *  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.javamail.testserver;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;

import javax.mail.Flags;
import javax.mail.internet.MimeMessage;
import javax.net.ssl.SSLSocketFactory;

import org.apache.commons.configuration.DefaultConfigurationBuilder;
import org.apache.james.dnsservice.api.DNSService;
import org.apache.james.domainlist.api.DomainListException;
import org.apache.james.domainlist.api.mock.SimpleDomainList;
import org.apache.james.filesystem.api.mock.MockFileSystem;
import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
import org.apache.james.imap.encode.main.DefaultLocalizer;
import org.apache.james.imap.main.DefaultImapDecoderFactory;
import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
import org.apache.james.imapserver.netty.IMAPServer;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageManager;
import org.apache.james.mailbox.acl.GroupMembershipResolver;
import org.apache.james.mailbox.acl.MailboxACLResolver;
import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
import org.apache.james.mailbox.acl.UnionMailboxACLResolver;
import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.store.Authenticator;
import org.apache.james.mailbox.store.StoreMailboxManager;
import org.apache.james.mailrepository.mock.MockMailRepositoryStore;
import org.apache.james.pop3server.netty.POP3Server;
import org.apache.james.protocols.lib.PortUtil;
import org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader;
import org.apache.james.queue.api.MailQueue;
import org.apache.james.queue.api.MailQueue.MailQueueItem;
import org.apache.james.queue.api.MailQueueFactory;
import org.apache.james.queue.file.FileMailQueueFactory;
import org.apache.james.rrt.api.RecipientRewriteTable;
import org.apache.james.rrt.api.RecipientRewriteTableException;
import org.apache.james.smtpserver.netty.SMTPServer;
import org.apache.james.user.api.UsersRepositoryException;
import org.apache.james.user.lib.mock.MockUsersRepository;
import org.apache.mailet.HostAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//James based POP3 or IMAP or SMTP server (for unittesting only)
public class MailServer {

    private POP3Server pop3Server;
    private IMAPServer imapServer;
    private SMTPServer smtpServer;
    private AlterableDNSServer dnsServer;
    private final MockUsersRepository usersRepository = new MockUsersRepository();
    private final MockFileSystem fileSystem = new MockFileSystem();
    private MockProtocolHandlerLoader protocolHandlerChain;
    private StoreMailboxManager<Long> mailboxManager;

    private MockMailRepositoryStore store;
    private DNSService dnsService;
    private MailQueueFactory queueFactory;
    private MailQueue queue;
    private final Semaphore sem = new Semaphore(0);
    private final Logger log = LoggerFactory.getLogger("Mock");

    public void ensureMsgCount(final int count) throws InterruptedException {
        sem.acquire(count);
    }

    private class Fetcher extends Thread {

        private final MailQueue queue;
        private final MessageManager mailbox;
        private final MailboxSession session;

        Fetcher(final MailQueue queue, final MessageManager mailbox, final MailboxSession session) {
            super();
            this.queue = queue;
            this.mailbox = mailbox;
            this.session = session;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    System.out.println("Await new mail ...");
                    final MailQueueItem item = queue.deQueue();
                    System.out.println("got it");
                    final MimeMessage msg = item.getMail().getMessage();
                    final ByteArrayOutputStream bout = new ByteArrayOutputStream();
                    msg.writeTo(bout);
                    mailbox.appendMessage(new ByteArrayInputStream(bout.toByteArray()), new Date(), session, true, new Flags());
                    item.done(true);
                    sem.release();
                    System.out.println("mail copied over");
                } catch (final Exception e) {
                    e.printStackTrace();
                    return;
                }
            }
        }

    }

    public MailServer() {
        super();
        try {
            usersRepository.addUser("serveruser", "serverpass");
        } catch (final UsersRepositoryException e) {
            throw new RuntimeException(e);
        }

    }

    public void start(final SmtpTestConfiguration smtpConfig, final Pop3TestConfiguration pop3Config, final ImapTestConfiguration imapConfig)
            throws Exception {
        setUpServiceManager();

        imapServer = new IMAPServer();

        imapServer.setImapEncoder(DefaultImapEncoderFactory.createDefaultEncoder(new DefaultLocalizer(), false));
        imapServer.setImapDecoder(DefaultImapDecoderFactory.createDecoder());

        pop3Server = new POP3Server();
        pop3Server.setProtocolHandlerLoader(protocolHandlerChain);

        smtpServer = new SMTPServer() {
            @Override
            protected java.lang.Class<? extends org.apache.james.protocols.lib.handler.HandlersPackage> getJMXHandlersPackage() {
                return RefinedJMXHandlersLoader.class;
            };

        };
        smtpServer.setProtocolHandlerLoader(protocolHandlerChain);
        smtpServer.setDNSService(dnsServer);

        imapServer.setFileSystem(fileSystem);
        pop3Server.setFileSystem(fileSystem);
        smtpServer.setFileSystem(fileSystem);

        imapServer.setLog(log);
        pop3Server.setLog(log);
        smtpServer.setLog(log);

        final MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, "serveruser", "INBOX");
        final MailboxSession session = mailboxManager.login("serveruser", "serverpass", LoggerFactory.getLogger("Test"));

        if (!mailboxManager.mailboxExists(mailboxPath, session)) {
            mailboxManager.createMailbox(mailboxPath, session);
        }

        imapServer.setImapProcessor(DefaultImapProcessorFactory.createXListSupportingProcessor(mailboxManager, null, null));//new StoreSubscriptionManager(new InMemoryMailboxSessionMapperFactory()), null));

        //setupTestMails(session, mailboxManager.getMailbox(mailboxPath, session));

        new Fetcher(queue, mailboxManager.getMailbox(mailboxPath, session), session).start();

        smtpConfig.init();
        pop3Config.init();
        imapConfig.init();

        smtpServer.configure(smtpConfig);
        pop3Server.configure(pop3Config);
        imapServer.configure(imapConfig);

        smtpServer.init();
        pop3Server.init();
        imapServer.init();

    }

    public void stop() throws Exception {

        if (protocolHandlerChain != null) {
            protocolHandlerChain.dispose();
        }

        if (imapServer != null) {
            imapServer.destroy();
        }

        if (pop3Server != null) {
            pop3Server.destroy();
        }

        if (smtpServer != null) {
            smtpServer.destroy();
        }

    }

    /* protected void setupTestMailsx(MailboxSession session, MessageManager mailbox) throws MailboxException {
         mailbox.appendMessage(new ByteArrayInputStream(content), new Date(), session, true, new Flags());
         byte[] content2 = ("EMPTY").getBytes();
         mailbox.appendMessage(new ByteArrayInputStream(content2), new Date(), session, true, new Flags());
     }*/

    protected void setUpServiceManager() throws Exception {
        protocolHandlerChain = new MockProtocolHandlerLoader();
        protocolHandlerChain.put("usersrepository", usersRepository);

        final InMemoryMailboxSessionMapperFactory factory = new InMemoryMailboxSessionMapperFactory();
        final MailboxACLResolver aclResolver = new UnionMailboxACLResolver();
        final GroupMembershipResolver groupMembershipResolver = new SimpleGroupMembershipResolver();
        mailboxManager = new StoreMailboxManager<Long>(factory, new Authenticator() {

            public boolean isAuthentic(final String userid, final CharSequence passwd) {
                try {
                    return usersRepository.test(userid, passwd.toString());
                } catch (final UsersRepositoryException e) {
                    e.printStackTrace();
                    return false;
                }
            }
        }, aclResolver, groupMembershipResolver);
        mailboxManager.init();

        protocolHandlerChain.put("mailboxmanager", mailboxManager);

        protocolHandlerChain.put("fileSystem", fileSystem);

        //smtp
        dnsServer = new AlterableDNSServer();
        store = new MockMailRepositoryStore();
        protocolHandlerChain.put("mailStore", store);
        protocolHandlerChain.put("dnsservice", dnsServer);
        protocolHandlerChain.put("org.apache.james.smtpserver.protocol.DNSService", dnsService);

        protocolHandlerChain.put("recipientrewritetable", new RecipientRewriteTable() {

            public void addRegexMapping(final String user, final String domain, final String regex) throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void removeRegexMapping(final String user, final String domain, final String regex)
                    throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void addAddressMapping(final String user, final String domain, final String address)
                    throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void removeAddressMapping(final String user, final String domain, final String address)
                    throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void addErrorMapping(final String user, final String domain, final String error) throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void removeErrorMapping(final String user, final String domain, final String error)
                    throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public Collection<String> getUserDomainMappings(final String user, final String domain) throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void addMapping(final String user, final String domain, final String mapping) throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void removeMapping(final String user, final String domain, final String mapping) throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public Map<String, Collection<String>> getAllMappings() throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void addAliasDomainMapping(final String aliasDomain, final String realDomain) throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public void removeAliasDomainMapping(final String aliasDomain, final String realDomain) throws RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }

            public Collection<String> getMappings(final String user, final String domain) throws ErrorMappingException,
            RecipientRewriteTableException {
                throw new UnsupportedOperationException("Not implemented");
            }
        });

        protocolHandlerChain.put("org.apache.james.smtpserver.protocol.DNSService", dnsService);

        final FileMailQueueFactory ff = new FileMailQueueFactory();// MockMailQueueFactory();
        ff.setLog(log);
        ff.setFileSystem(fileSystem);
        queueFactory = ff;

        queue = queueFactory.getQueue(MailQueueFactory.SPOOL);
        protocolHandlerChain.put("mailqueuefactory", queueFactory);
        protocolHandlerChain.put("domainlist", new SimpleDomainList() {

            @Override
            public String getDefaultDomain() {
                return "localhost";
            }

            @Override
            public String[] getDomains() throws DomainListException {
                return new String[] { "localhost" };
            }

            @Override
            public boolean containsDomain(final String serverName) {
                return "localhost".equals(serverName);
            }
        });

    }

    /**
     * @return the queue
     */
    public MailQueue getQueue() {
        return queue;
    }

    public static File getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) throws FileNotFoundException {

        File configFile = null;
        final URL configURL = MailServer.class.getClassLoader().getResource(fileNameFromClasspath);
        if (configURL != null) {
            try {
                configFile = new File(configURL.toURI());
            } catch (URISyntaxException e) {
                configFile = new File(configURL.getPath());
            }

            //Java 7 only
            /*if(!configFile.exists()) {
                try {
                    configFile = Paths.get(configURL.toURI()).toFile();
                } catch (URISyntaxException e) {
                    throw new FileNotFoundException("Failed to load " + fileNameFromClasspath+ " due to "+e);
                }
            }*/

            if (configFile.exists()) {
                return configFile;
            } else {
                throw new FileNotFoundException("Cannot read from "+configFile.getAbsolutePath()+" (original resource was "+fileNameFromClasspath+", URL: "+configURL+"), because the file does not exist");
            }
            
        } else {
            throw new FileNotFoundException("Failed to load " + fileNameFromClasspath+", because resource cannot be found within the classpath");
        }

    }

    public static abstract class AbstractTestConfiguration extends DefaultConfigurationBuilder {

        private final int listenerPort = PortUtil.getNonPrivilegedPort();

        /**
         * @return the listenerPort
         */
        public int getListenerPort() {
            return listenerPort;
        }

        public AbstractTestConfiguration enableSSL(final boolean enableStartTLS, final boolean enableSSL) throws FileNotFoundException {
            addProperty("tls.[@startTLS]", enableStartTLS);
            addProperty("tls.[@socketTLS]", enableSSL);
            addProperty("tls.keystore", "file://" + getAbsoluteFilePathFromClassPath("dummykeystore.jks").getAbsolutePath());
            addProperty("tls.secret", "123456");
            addProperty("tls.provider", "org.bouncycastle.jce.provider.BouncyCastleProvider");
            return this;
        }

        public void init() {
            addProperty("[@enabled]", true);
            addProperty("bind", "127.0.0.1:" + this.listenerPort);
            addProperty("connectiontimeout", "360000");
            //addProperty("jmxName", getServertype().name()+"on"+this.listenerPort);
            addProperty("helloName", "jamesserver");
            addProperty("helloName.[@autodetect]", false);
        }

    }

    public static class Pop3TestConfiguration extends AbstractTestConfiguration {

        @Override
        public void init() {
            super.init();

            addProperty("helloName", "pop3 on port " + getListenerPort());

            addProperty("handlerchain.[@coreHandlersPackage]", RefinedCoreCmdHandlerLoader.class.getName());

        }

    }

    public static class ImapTestConfiguration extends AbstractTestConfiguration {

        @Override
        public void init() {
            super.init();

            addProperty("helloName", "imap on port " + getListenerPort());

        }

    }

    public static class SmtpTestConfiguration extends AbstractTestConfiguration {

        @Override
        public void init() {
            super.init();
            addProperty("handlerchain.handler[@class]", RefinedSmtpCoreCmdHandlerLoader.class.getName());

        }

        public SmtpTestConfiguration setRequireAuth(final boolean requireAuth) {

            addProperty("authRequired", requireAuth);
            return this;
        }

        public SmtpTestConfiguration setHeloEhloEnforcement(final boolean heloEhloEnforcement) {

            addProperty("heloEhloEnforcement", heloEhloEnforcement);
            return this;
        }

    }

    public static class DummySocketFactory extends SSLSocketFactory {

        @Override
        public Socket createSocket(final String host, final int port) throws IOException, UnknownHostException {
            throw new IOException("dummy socket factory");
        }

        @Override
        public Socket createSocket(final InetAddress host, final int port) throws IOException {
            throw new IOException("dummy socket factory");
        }

        @Override
        public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) throws IOException,
                UnknownHostException {
            throw new IOException("dummy socket factory");
        }

        @Override
        public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddress, final int localPort)
                throws IOException {
            throw new IOException("dummy socket factory");
        }

        @Override
        public Socket createSocket(final Socket arg0, final String arg1, final int arg2, final boolean arg3) throws IOException {
            throw new IOException("dummy socket factory");
        }

        @Override
        public String[] getDefaultCipherSuites() {
            return new String[0];
        }

        @Override
        public String[] getSupportedCipherSuites() {
            return new String[0];
        }

    }

    private final class AlterableDNSServer implements DNSService {

        private InetAddress localhostByName = null;

        public Collection<String> findMXRecords(final String hostname) {
            final List<String> res = new ArrayList<String>();
            if (hostname == null) {
                return res;
            }
            if ("james.apache.org".equals(hostname)) {
                res.add("nagoya.apache.org");
            }
            return res;
        }

        public Iterator<HostAddress> getSMTPHostAddresses(final String domainName) {
            throw new UnsupportedOperationException("Unimplemented mock service");
        }

        public InetAddress[] getAllByName(final String host) throws UnknownHostException {
            return new InetAddress[] { getByName(host) };
        }

        public InetAddress getByName(final String host) throws UnknownHostException {
            if (getLocalhostByName() != null) {
                if ("127.0.0.1".equals(host)) {
                    return getLocalhostByName();
                }
            }

            if ("0.0.0.0".equals(host)) {
                return InetAddress.getByName("0.0.0.0");
            }

            if ("james.apache.org".equals(host)) {
                return InetAddress.getByName("james.apache.org");
            }

            if ("abgsfe3rsf.de".equals(host)) {
                throw new UnknownHostException();
            }

            if ("128.0.0.1".equals(host) || "192.168.0.1".equals(host) || "127.0.0.1".equals(host) || "127.0.0.0".equals(host)
                    || "255.0.0.0".equals(host) || "255.255.255.255".equals(host)) {
                return InetAddress.getByName(host);
            }

            throw new UnsupportedOperationException("getByName not implemented in mock for host: " + host);
        }

        public Collection<String> findTXTRecords(final String hostname) {
            final List<String> res = new ArrayList<String>();
            if (hostname == null) {
                return res;
            }

            if ("2.0.0.127.bl.spamcop.net.".equals(hostname)) {
                res.add("Blocked - see http://www.spamcop.net/bl.shtml?127.0.0.2");
            }
            return res;
        }

        public InetAddress getLocalhostByName() {
            return localhostByName;
        }

        public void setLocalhostByName(final InetAddress localhostByName) {
            this.localhostByName = localhostByName;
        }

        public String getHostName(final InetAddress addr) {
            return addr.getHostName();
        }

        public InetAddress getLocalHost() throws UnknownHostException {
            return InetAddress.getLocalHost();
        }
    }

}
