/*
 * 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.vxquery.xtest;

import org.apache.hyracks.control.cc.ClusterControllerService;
import org.apache.hyracks.control.nc.NodeControllerService;
import org.mortbay.jetty.Server;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class XTest {
    private XTestOptions opts;
    private Server server;
    private ExecutorService eSvc;
    private List<ResultReporter> reporters;
    private TestRunnerFactory trf;
    private int count;
    private int finishCount;
    private static NodeControllerService nc;
    private static ClusterControllerService cc;

    XTest(XTestOptions opts) {
        this.opts = opts;
        reporters = new ArrayList<>();
    }

    void init() throws Exception {
        finishCount = 0;
        if (opts.threads <= 0) {
            opts.threads = 1;
        }
        eSvc = Executors.newFixedThreadPool(opts.threads);
        if (opts.port > 0) {
            ServletReporterImpl servletHandler = new ServletReporterImpl();
            reporters.add(servletHandler);
            server = new Server(opts.port);
            server.addHandler(servletHandler);
            server.start();
        }
        if (opts.htmlReport != null) {
            reporters.add(new HTMLFileReporterImpl(new File(opts.htmlReport)));
        }
        if (opts.xmlReport != null) {
            reporters.add(new XMLFileReporterImpl(new File(opts.xmlReport)));
        }
        if (opts.diffable != null) {
            reporters.add(new LineFileReporterImpl(new File(opts.diffable)));
        }
        reporters.add(new ResultReporter() {
            @Override
            public void close() {
            }

            @Override
            public void reportResult(TestCaseResult result) {
                synchronized (XTest.this) {
                    finishCount++;
                    if (finishCount >= count) {
                        XTest.this.notifyAll();
                    }
                }
            }
        });
        cc = TestClusterUtil.startCC();
        nc = TestClusterUtil.startNC();
        trf = new TestRunnerFactory(opts);
        trf.registerReporters(reporters);
        TestCaseFactory tcf = new TestCaseFactory(trf, eSvc, opts);
        count = tcf.process();
    }

    synchronized void waitForCompletion() throws InterruptedException {
        while (finishCount < count) {
            wait();
        }
        if (opts.keepalive > 0) {
            Thread.sleep(opts.keepalive);
        }
        eSvc.shutdown();
        while (!eSvc.awaitTermination(5L, TimeUnit.SECONDS)) {
            System.err.println("Failed to close all threads, trying again...");
        }
        for (ResultReporter r : reporters) {
            r.close();
        }
        try {
            TestClusterUtil.stopCluster(cc, nc);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            eSvc.awaitTermination(opts.keepalive, TimeUnit.MILLISECONDS);
        } finally {
            try {
                if (server != null) {
                    server.stop();
                }
                trf.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
