/**
 *  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.net.InetAddress;
import java.net.Socket;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
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();
        }
    }

}
