/**
 * 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 com.twitter.distributedlog;

import com.google.common.base.Optional;
import com.twitter.distributedlog.impl.metadata.BKDLConfig;
import com.twitter.distributedlog.metadata.DLMetadata;
import org.apache.bookkeeper.conf.ServerConfiguration;
import org.apache.bookkeeper.proto.BookieServer;
import org.apache.bookkeeper.shims.zk.ZooKeeperServerShim;
import org.apache.bookkeeper.util.IOUtils;
import org.apache.bookkeeper.util.LocalBookKeeper;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.BindException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Utility class for setting up bookkeeper ensembles
 * and bringing individual bookies up and down
 */
public class LocalDLMEmulator {
    private static final Logger LOG = LoggerFactory.getLogger(LocalDLMEmulator.class);

    public static final String DLOG_NAMESPACE = "/messaging/distributedlog";

    private static final int DEFAULT_BOOKIE_INITIAL_PORT = 0; // Use ephemeral ports
    private static final int DEFAULT_ZK_TIMEOUT_SEC = 10;
    private static final int DEFAULT_ZK_PORT = 2181;
    private static final String DEFAULT_ZK_HOST = "127.0.0.1";
    private static final String DEFAULT_ZK_ENSEMBLE = DEFAULT_ZK_HOST + ":" + DEFAULT_ZK_PORT;
    private static final int DEFAULT_NUM_BOOKIES = 3;
    private static final ServerConfiguration DEFAULT_SERVER_CONFIGURATION = new ServerConfiguration();

    private final String zkEnsemble;
    private final URI uri;
    private final List<File> tmpDirs = new ArrayList<File>();
    private final int zkTimeoutSec;
    private final Thread bkStartupThread;
    private final String zkHost;
    private final int zkPort;
    private final int numBookies;

    public static class Builder {
        private int zkTimeoutSec = DEFAULT_ZK_TIMEOUT_SEC;
        private int numBookies = DEFAULT_NUM_BOOKIES;
        private String zkHost = DEFAULT_ZK_HOST;
        private int zkPort = DEFAULT_ZK_PORT;
        private int initialBookiePort = DEFAULT_BOOKIE_INITIAL_PORT;
        private boolean shouldStartZK = true;
        private Optional<ServerConfiguration> serverConf = Optional.absent();

        public Builder numBookies(int numBookies) {
            this.numBookies = numBookies;
            return this;
        }
        public Builder zkHost(String zkHost) {
            this.zkHost = zkHost;
            return this;
        }
        public Builder zkPort(int zkPort) {
            this.zkPort = zkPort;
            return this;
        }
        public Builder zkTimeoutSec(int zkTimeoutSec) {
            this.zkTimeoutSec = zkTimeoutSec;
            return this;
        }
        public Builder initialBookiePort(int initialBookiePort) {
            this.initialBookiePort = initialBookiePort;
            return this;
        }
        public Builder shouldStartZK(boolean shouldStartZK) {
            this.shouldStartZK = shouldStartZK;
            return this;
        }
        public Builder serverConf(ServerConfiguration serverConf) {
            this.serverConf = Optional.of(serverConf);
            return this;
        }

        public LocalDLMEmulator build() throws Exception {
            ServerConfiguration conf = null;
            if (serverConf.isPresent()) {
                conf = serverConf.get();
            } else {
                conf = (ServerConfiguration) DEFAULT_SERVER_CONFIGURATION.clone();
                conf.setZkTimeout(zkTimeoutSec * 1000);
            }
            ServerConfiguration newConf = new ServerConfiguration();
            newConf.loadConf(conf);
            newConf.setAllowLoopback(true);

            return new LocalDLMEmulator(numBookies, shouldStartZK, zkHost, zkPort,
                initialBookiePort, zkTimeoutSec, newConf);
        }
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    private LocalDLMEmulator(final int numBookies, final boolean shouldStartZK, final String zkHost, final int zkPort, final int initialBookiePort, final int zkTimeoutSec, final ServerConfiguration serverConf) throws Exception {
        this.numBookies = numBookies;
        this.zkHost = zkHost;
        this.zkPort = zkPort;
        this.zkEnsemble = zkHost + ":" + zkPort;
        this.uri = URI.create("distributedlog://" + zkEnsemble + DLOG_NAMESPACE);
        this.zkTimeoutSec = zkTimeoutSec;
        this.bkStartupThread = new Thread() {
            public void run() {
                try {
                    LOG.info("Starting {} bookies : allowLoopback = {}", numBookies, serverConf.getAllowLoopback());
                    LocalBookKeeper.startLocalBookies(zkHost, zkPort, numBookies, shouldStartZK, initialBookiePort, serverConf);
                    LOG.info("{} bookies are started.");
                } catch (InterruptedException e) {
                    // go away quietly
                } catch (Exception e) {
                    LOG.error("Error starting local bk", e);
                }
            }
        };
    }

    public void start() throws Exception {
        bkStartupThread.start();
        if (!LocalBookKeeper.waitForServerUp(zkEnsemble, zkTimeoutSec*1000)) {
            throw new Exception("Error starting zookeeper/bookkeeper");
        }
        int bookiesUp = checkBookiesUp(numBookies, zkTimeoutSec);
        assert (numBookies == bookiesUp);
        // Provision "/messaging/distributedlog" namespace
        DLMetadata.create(new BKDLConfig(zkEnsemble, "/ledgers")).create(uri);
    }

    public void teardown() throws Exception {
        if (bkStartupThread != null) {
            bkStartupThread.interrupt();
            bkStartupThread.join();
        }
        for (File dir : tmpDirs) {
            FileUtils.deleteDirectory(dir);
        }
    }

    public String getZkServers() {
        return zkEnsemble;
    }

    public URI getUri() {
        return uri;
    }

    public BookieServer newBookie() throws Exception {
        ServerConfiguration bookieConf = new ServerConfiguration();
        bookieConf.setZkTimeout(zkTimeoutSec * 1000);
        bookieConf.setBookiePort(0);
        bookieConf.setAllowLoopback(true);
        File tmpdir = File.createTempFile("bookie" + UUID.randomUUID() + "_",
            "test");
        if (!tmpdir.delete()) {
            LOG.debug("Fail to delete tmpdir " + tmpdir);
        }
        if (!tmpdir.mkdir()) {
            throw new IOException("Fail to create tmpdir " + tmpdir);
        }
        tmpDirs.add(tmpdir);

        bookieConf.setZkServers(zkEnsemble);
        bookieConf.setJournalDirName(tmpdir.getPath());
        bookieConf.setLedgerDirNames(new String[]{tmpdir.getPath()});

        BookieServer b = new BookieServer(bookieConf);
        b.start();
        for (int i = 0; i < 10 && !b.isRunning(); i++) {
            Thread.sleep(10000);
        }
        if (!b.isRunning()) {
            throw new IOException("Bookie would not start");
        }
        return b;
    }

    /**
     * Check that a number of bookies are available
     *
     * @param count number of bookies required
     * @param timeout number of seconds to wait for bookies to start
     * @throws java.io.IOException if bookies are not started by the time the timeout hits
     */
    public int checkBookiesUp(int count, int timeout) throws Exception {
        ZooKeeper zkc = connectZooKeeper(zkHost, zkPort, zkTimeoutSec);
        try {
            int mostRecentSize = 0;
            for (int i = 0; i < timeout; i++) {
                try {
                    List<String> children = zkc.getChildren("/ledgers/available",
                        false);
                    children.remove("readonly");
                    mostRecentSize = children.size();
                    if ((mostRecentSize > count) || LOG.isDebugEnabled()) {
                        LOG.info("Found " + mostRecentSize + " bookies up, "
                            + "waiting for " + count);
                        if ((mostRecentSize > count) || LOG.isTraceEnabled()) {
                            for (String child : children) {
                                LOG.info(" server: " + child);
                            }
                        }
                    }
                    if (mostRecentSize == count) {
                        break;
                    }
                } catch (KeeperException e) {
                    // ignore
                }
                Thread.sleep(1000);
            }
            return mostRecentSize;
        } finally {
            zkc.close();
        }
    }

    public static String getBkLedgerPath() {
        return "/ledgers";
    }

    public static ZooKeeper connectZooKeeper(String zkHost, int zkPort)
        throws IOException, KeeperException, InterruptedException {
            return connectZooKeeper(zkHost, zkPort, DEFAULT_ZK_TIMEOUT_SEC);
    }

    public static ZooKeeper connectZooKeeper(String zkHost, int zkPort, int zkTimeoutSec)
        throws IOException, KeeperException, InterruptedException {
        final CountDownLatch latch = new CountDownLatch(1);
        final String zkHostPort = zkHost + ":" + zkPort;

        ZooKeeper zkc = new ZooKeeper(zkHostPort, zkTimeoutSec * 1000, new Watcher() {
            public void process(WatchedEvent event) {
                if (event.getState() == Event.KeeperState.SyncConnected) {
                    latch.countDown();
                }
            }
        });
        if (!latch.await(zkTimeoutSec, TimeUnit.SECONDS)) {
            throw new IOException("Zookeeper took too long to connect");
        }
        return zkc;
    }

    public static URI createDLMURI(String path) throws Exception {
        return createDLMURI(DEFAULT_ZK_ENSEMBLE, path);
    }

    public static URI createDLMURI(String zkServers, String path) throws Exception {
        return URI.create("distributedlog://" + zkServers + DLOG_NAMESPACE + path);
    }

    /**
     * Try to start zookkeeper locally on any port.
     */
    public static Pair<ZooKeeperServerShim, Integer> runZookeeperOnAnyPort(File zkDir) throws Exception {
        return runZookeeperOnAnyPort((int) (Math.random()*10000+7000), zkDir);
    }

    /**
     * Try to start zookkeeper locally on any port beginning with some base port.
     * Dump some socket info when bind fails.
     */
    public static Pair<ZooKeeperServerShim, Integer> runZookeeperOnAnyPort(int basePort, File zkDir) throws Exception {

        final int MAX_RETRIES = 20;
        final int MIN_PORT = 1025;
        final int MAX_PORT = 65535;
        ZooKeeperServerShim zks = null;
        int zkPort = basePort;
        boolean success = false;
        int retries = 0;

        while (!success) {
            try {
                LOG.info("zk trying to bind to port " + zkPort);
                zks = LocalBookKeeper.runZookeeper(1000, zkPort, zkDir);
                success = true;
            } catch (BindException be) {
                retries++;
                if (retries > MAX_RETRIES) {
                    throw be;
                }
                zkPort++;
                if (zkPort > MAX_PORT) {
                    zkPort = MIN_PORT;
                }
            }
        }

        return Pair.of(zks, zkPort);
    }

    public static void main(String[] args) throws Exception {
        try {
            if (args.length < 1) {
                System.out.println("Usage: LocalDLEmulator <zk_port>");
                System.exit(-1);
            }

            final int zkPort = Integer.parseInt(args[0]);
            final File zkDir = IOUtils.createTempDir("distrlog", "zookeeper");
            final LocalDLMEmulator localDlm = LocalDLMEmulator.newBuilder()
                .zkPort(zkPort)
                .build();

            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    try {
                        localDlm.teardown();
                        FileUtils.deleteDirectory(zkDir);
                        System.out.println("ByeBye!");
                    } catch (Exception e) {
                        // do nothing
                    }
                }
            });
            localDlm.start();

            System.out.println(String.format(
                "DistributedLog Sandbox is running now. You could access distributedlog://%s:%s",
                DEFAULT_ZK_HOST,
                zkPort));
        } catch (Exception ex) {
            System.out.println("Exception occurred running emulator " + ex);
        }
    }
}
