//////////////////////////////////////////////////////////////////////
//
// Given is a mock process which runs indefinitely and blocks the
// program. Right now the only way to stop the program is to send a
// SIGINT (Ctrl-C). Killing a process like that is not graceful, so we
// want to try to gracefully stop the process first.
//
// Change the program to do the following:
//   1. On SIGINT try to gracefully stop the process using
//          `proc.Stop()`
//   2. If SIGINT is called again, just kill the program (last resort)
//

package main

import (
	"os"
	"os/signal"
	"syscall"
)

func solution1() {
	// Create a process
	proc := MockProcess{}

	sig := make(chan os.Signal, 1)
	signal.Notify(sig, syscall.SIGINT)

	// Run the process (blocking)
	go proc.Run()
	<-sig

	done := make(chan bool, 1)
	go func() {
		proc.Stop()
		done <- true
	}()

	select {
	case <-done:
		return
	case <-sig:
		return
	}
}

func solution2() {
	// Create a process
	proc := MockProcess{}

	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		<-c
		signal.Reset() // reset interrupt handler and get back to standard behaviour : killing the process
		proc.Stop()
	}()

	// Run the process (blocking)
	proc.Run()
}

func main() {
	solution1()
	solution2() // must run after Solution1 because the 2nd SIGINT will be fatal
}
