package service;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.concurrent.CountDownLatch;

public class Hello {

    public static void main(String[] args) {
        log("started at " + new Date());

        CountDownLatch countDownLatch = new CountDownLatch(1);
        Thread workerThread = new WorkerThread(countDownLatch);
        workerThread.start();

        Runtime.getRuntime().addShutdownHook(new ShutdownThread(workerThread, countDownLatch));
    }

    private static class WorkerThread extends Thread {
        private CountDownLatch countDownLatch;

        public WorkerThread(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            // do your work until the thread is interrupted
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    Thread.sleep(2000);
                    log("working at " + new Date());
                }
            } catch (InterruptedException ignored) {

            }

            // do clean up, shut down
            for (int i=0; i<3; i++) {
                try {
                    Thread.sleep(1000);
                    log("cleaning up at " + new Date());
                } catch (InterruptedException ignored) {

                }
            }

            // notify the controller thread that we have finished
            countDownLatch.countDown();
        }
    }

    private static class ShutdownThread extends Thread {
        private final Thread workerThread;
        private CountDownLatch countDownLatch;

        public ShutdownThread(Thread workerThread, CountDownLatch countDownLatch) {
            this.workerThread = workerThread;
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            log("shutdown requested at " + new Date());

            // request worker thread to finish
            workerThread.interrupt();

            // wait for the worker thread to finish
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log("shutdown at " + new Date());
        }
    }


    private static void log(String val) {
        try {
            PrintWriter pw = new PrintWriter(new FileOutputStream("service_demo.log", true));
            pw.println(val);
            pw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
