/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed 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.onosproject.checkstyle;

import com.puppycrawl.tools.checkstyle.api.CheckstyleException;

import java.io.IOException;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static java.nio.file.StandardOpenOption.*;

/**
 * Main program for executing scenario test warden.
 */
public final class Main {

    private static long POLLING_INTERVAL = 1000; //ms

    // Public construction forbidden
    private Main(String[] args) {
    }

    /**
     * Main entry point for the cell warden.
     *
     * @param args command-line arguments
     */
    public static void main(String[] args)
            throws CheckstyleException, IOException {
        startServer(args);
    }

    // Monitors another PID and exit when that process exits
    private static void watchProcess(String pid) {
        if (pid == null || pid.equals("0")) {
            return;
        }
        Timer timer = new Timer(true); // start as a daemon, so we don't hang shutdown
        timer.scheduleAtFixedRate(new TimerTask() {
            private String cmd = "kill -s 0 " + pid;
            @Override
            public void run() {
                try {
                    Process p = Runtime.getRuntime().exec(cmd);
                    p.waitFor();
                    if (p.exitValue() != 0) {
                        System.err.println("shutting down...");
                        System.exit(0);
                    }
                } catch (IOException | InterruptedException e) {
                    //no-op
                    e.printStackTrace();
                }
            }
        }, POLLING_INTERVAL, POLLING_INTERVAL);
    }

    // Initiates a server.
    private static void startServer(String[] args) throws IOException, CheckstyleException {
        String portLock = args[0];
        String buckPid = args[1];
        String checkstyleFile = args[2];
        String suppressionsFile = args[3];

        // Use a file lock to ensure only one copy of the daemon runs
        Path portLockPath = Paths.get(portLock);
        FileChannel channel = FileChannel.open(portLockPath, WRITE, CREATE);
        FileLock lock = channel.tryLock();
        if (lock == null) {
            System.out.println("Server is already running");
            System.exit(1);
        } //else, hold the lock until the JVM exits

        // Start the server and bind it to a random port
        ServerSocket server = new ServerSocket(0);

        // Monitor the parent buck process
        watchProcess(buckPid);

        // Set up hook to clean up after ourselves
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                if (channel != null) {
                    channel.truncate(0);
                    channel.close();
                }
                System.err.println("tear down...");
                Files.delete(portLockPath);
            } catch (IOException e) {
                //no-op: shutting down
                e.printStackTrace();
            }
        }));

        // Write the bound port to the port file
        int port = server.getLocalPort();
        channel.truncate(0);
        channel.write(ByteBuffer.wrap(Integer.toString(port).getBytes()));

        // Instantiate a Checkstyle runner and executor; serve until exit...
        CheckstyleRunner runner = new CheckstyleRunner(checkstyleFile, suppressionsFile);
        ExecutorService executor = Executors.newCachedThreadPool();
        while (true) {
            try {
                executor.submit(runner.checkClass(server.accept()));
            } catch (Exception e) {
                e.printStackTrace();
                //no-op
            }
        }
    }
}
