/*
 * 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.tinkerpop.gremlin.driver.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.tinkerpop.gremlin.driver.Channelizer;
import org.apache.tinkerpop.gremlin.driver.Client;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.util.ser.Serializers;
import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

/**
 * An internal application used to test out configuration parameters for Gremlin Driver.
 *
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public class ProfilingApplication {

    private static final Random random = new Random();
    private static final String[] scripts = new String[]{
            "g.V()",
            "g.V(1).out('knows')",
            "g.V(1).out('knows').has('name','josh')",
            "g.V(1).as(\"a\").out(\"knows\").as(\"b\").select(\"a\", \"b\")",
            "g.V(1).as(\"a\").out(\"knows\").as(\"b\").select(\"a\", \"b\").by(\"name\")",
            "g.V().hasLabel(\"person\").as(\"p\").map(__.bothE().label().groupCount()).as(\"r\").select(\"p\", \"r\")",
            "g.V().choose(__.outE().count().is(0L), __.as(\"a\"), __.as(\"b\")).choose(__.select(\"a\"), __.select(\"a\"), __.select(\"b\"))",
            "g.V().group(\"a\").by(T.label).by(outE().values(\"weight\").sum()).cap(\"a\")",
            "g.V().repeat(__.union(__.out(\"knows\").group(\"a\").by(\"age\"), __.out(\"created\").group(\"b\").by(\"name\").by(count())).group(\"a\").by(\"name\")).times(2).cap(\"a\", \"b\")",
            "g.V().match(\n" +
            "  as(\"a\").out(\"knows\").as(\"b\"),\n" +
            "  as(\"b\").out(\"created\").has(\"name\", \"lop\"),\n" +
            "  as(\"b\").match(\n" +
            "  as(\"b\").out(\"created\").as(\"d\"),\n" +
            "  as(\"d\").in(\"created\").as(\"c\")).select(\"c\").as(\"c\")).<Vertex>select(\"a\", \"b\", \"c\")"
    };

    private final Cluster cluster;
    private final int requests;
    private final String executionName;
    private final String script;
    private final int tooSlowThreshold;
    private final boolean exercise;

    private final ExecutorService executor;

    public ProfilingApplication(final String executionName, final Cluster cluster, final int requests, final ExecutorService executor,
                                final String script, final int tooSlowThreshold, final boolean exercise) {
        this.executionName = executionName;
        this.cluster = cluster;
        this.requests = requests;
        this.executor = executor;
        this.script = script;
        this.tooSlowThreshold = tooSlowThreshold;
        this.exercise = exercise;
    }

    public long execute() throws Exception {
        final AtomicInteger tooSlow = new AtomicInteger(0);

        final Client client = cluster.connect();
        final String executionId = "[" + executionName + "]";
        try {
            final CountDownLatch latch = new CountDownLatch(requests);
            client.init();

            final long start = System.nanoTime();
            IntStream.range(0, requests).forEach(i -> {
                final String s = exercise ? chooseScript() : script;
                client.submitAsync(s).thenAcceptAsync(r -> {
                    try {
                        r.all().get(tooSlowThreshold, TimeUnit.MILLISECONDS);
                    } catch (TimeoutException ex) {
                        tooSlow.incrementAndGet();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    } finally {
                        latch.countDown();
                    }
                }, executor);
            });

            // finish once all requests are accounted for
            latch.await();

            final long end = System.nanoTime();
            final long total = end - start;
            final double totalSeconds = total / 1000000000d;
            final long requestCount = requests;
            final long reqSec = Math.round(requestCount / totalSeconds);
            System.out.println(String.format(StringUtils.rightPad(executionId, 10) + " requests: %s | time(s): %s | req/sec: %s | too slow: %s", requestCount, StringUtils.rightPad(String.valueOf(totalSeconds), 14), StringUtils.rightPad(String.valueOf(reqSec), 7), exercise ? "N/A" : tooSlow.get()));
            return reqSec;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        } finally {
            client.close();
        }
    }

    private String chooseScript() {
        return scripts[random.nextInt(scripts.length - 1)];
    }

    public static void main(final String[] args) {
        final Map<String,Object> options = ElementHelper.asMap(args);
        final boolean noExit = Boolean.parseBoolean(options.getOrDefault("noExit", "false").toString());
        final int parallelism = Integer.parseInt(options.getOrDefault("parallelism", "16").toString());
        final BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("profiler-%d").build();
        final ExecutorService executor = Executors.newFixedThreadPool(parallelism, threadFactory);

        final String host = options.getOrDefault("host", "localhost").toString();
        final int minExpectedRps = Integer.parseInt(options.getOrDefault("minExpectedRps", "1000").toString());
        final int timeout = Integer.parseInt(options.getOrDefault("timeout", "1200000").toString());
        final int warmups = Integer.parseInt(options.getOrDefault("warmups", "5").toString());
        final int executions = Integer.parseInt(options.getOrDefault("executions", "10").toString());
        final int nioPoolSize = Integer.parseInt(options.getOrDefault("nioPoolSize", "1").toString());
        final int requests = Integer.parseInt(options.getOrDefault("requests", "10000").toString());
        final int minConnectionPoolSize = Integer.parseInt(options.getOrDefault("minConnectionPoolSize", "256").toString());
        final int maxConnectionPoolSize = Integer.parseInt(options.getOrDefault("maxConnectionPoolSize", "256").toString());
        final int minSimultaneousUsagePerConnection = Integer.parseInt(options.getOrDefault("minSimultaneousUsagePerConnection", "8").toString());
        final int maxSimultaneousUsagePerConnection = Integer.parseInt(options.getOrDefault("maxSimultaneousUsagePerConnection", "32").toString());
        final int maxInProcessPerConnection = Integer.parseInt(options.getOrDefault("maxInProcessPerConnection", "64").toString());
        final int minInProcessPerConnection = Integer.parseInt(options.getOrDefault("minInProcessPerConnection", "16").toString());
        final int maxWaitForConnection = Integer.parseInt(options.getOrDefault("maxWaitForConnection", "3000").toString());
        final int workerPoolSize = Integer.parseInt(options.getOrDefault("workerPoolSize", "2").toString());
        final int tooSlowThreshold = Integer.parseInt(options.getOrDefault("tooSlowThreshold", "125").toString());
        final String channelizer = options.getOrDefault("channelizer", Channelizer.WebSocketChannelizer.class.getName()).toString();
        final String serializer = options.getOrDefault("serializer", Serializers.GRAPHBINARY_V1D0.name()).toString();

        final boolean exercise = Boolean.parseBoolean(options.getOrDefault("exercise", "false").toString());
        final String script = options.getOrDefault("script", "1+1").toString();

        final Cluster cluster = Cluster.build(host)
                .minConnectionPoolSize(minConnectionPoolSize)
                .maxConnectionPoolSize(maxConnectionPoolSize)
                .minSimultaneousUsagePerConnection(minSimultaneousUsagePerConnection)
                .maxSimultaneousUsagePerConnection(maxSimultaneousUsagePerConnection)
                .minInProcessPerConnection(minInProcessPerConnection)
                .maxInProcessPerConnection(maxInProcessPerConnection)
                .nioPoolSize(nioPoolSize)
                .channelizer(channelizer)
                .maxWaitForConnection(maxWaitForConnection)
                .serializer(Serializers.valueOf(serializer))
                .workerPoolSize(workerPoolSize).create();

        try {
            if (exercise) {
                System.out.println("--------------------------INITIALIZATION--------------------------");
                final Client client = cluster.connect();
                client.submit("graph.clear()").all().join();
                System.out.println("Cleared existing 'graph'");

                client.submit("TinkerFactory.generateModern(graph)").all().join();
                client.close();

                System.out.println("Modern graph loaded");
            }

            final Object fileName = options.get("store");
            final File f = null == fileName ? null : new File(fileName.toString());
            if (f != null && f.length() == 0) {
                try (final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(f, true)))) {
                    writer.println("parallelism\tnioPoolSize\tminConnectionPoolSize\tmaxConnectionPoolSize\tminSimultaneousUsagePerConnection\tmaxSimultaneousUsagePerConnection\tminInProcessPerConnection\tmaxInProcessPerConnection\tworkerPoolSize\trequestPerSecond");
                }
            }

            // not much point to continuing with a line of tests if we can't get at least minExpectedRps.
            final AtomicBoolean meetsRpsExpectation = new AtomicBoolean(true);
            System.out.println("---------------------------WARMUP CYCLE---------------------------");
            for (int ix = 0; ix < warmups && meetsRpsExpectation.get(); ix++) {
                final long averageRequestsPerSecond = new ProfilingApplication("warmup-" + (ix + 1), cluster, 1000, executor, script, tooSlowThreshold, exercise).execute();
                meetsRpsExpectation.set(averageRequestsPerSecond > minExpectedRps);
                TimeUnit.SECONDS.sleep(1); // pause between executions
            }

            final AtomicBoolean exceededTimeout = new AtomicBoolean(false);
            long totalRequestsPerSecond = 0;

            // no need to execute this if we didn't pass the basic expectation in the warmups
            if (exercise || meetsRpsExpectation.get()) {
                final long start = System.nanoTime();
                System.out.println("----------------------------TEST CYCLE----------------------------");
                for (int ix = 0; ix < executions && !exceededTimeout.get(); ix++) {
                    totalRequestsPerSecond += new ProfilingApplication("test-" + (ix + 1), cluster, requests, executor, script, tooSlowThreshold, exercise).execute();
                    exceededTimeout.set((System.nanoTime() - start) > TimeUnit.NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS));
                    TimeUnit.SECONDS.sleep(1); // pause between executions
                }
            }

            final int averageRequestPerSecond = !meetsRpsExpectation.get() || exceededTimeout.get() ? 0 : Math.round(totalRequestsPerSecond / executions);
            System.out.println(String.format("avg req/sec: %s", averageRequestPerSecond));
            if (f != null) {
                try (final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(f, true)))) {
                    writer.println(String.join("\t", String.valueOf(parallelism), String.valueOf(nioPoolSize), String.valueOf(minConnectionPoolSize), String.valueOf(maxConnectionPoolSize), String.valueOf(minSimultaneousUsagePerConnection), String.valueOf(maxSimultaneousUsagePerConnection), String.valueOf(minInProcessPerConnection), String.valueOf(maxInProcessPerConnection), String.valueOf(workerPoolSize), String.valueOf(averageRequestPerSecond)));
                }
            }

            if (!noExit) System.exit(0);
        } catch (Exception ex) {
            ex.printStackTrace();
            if (!noExit) System.exit(1);
        } finally {
            executor.shutdown();
            cluster.close();
        }
    }
}
