package main

import (
	"flag"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strconv"
	"syscall"
)

var (
	path       string
	huppidfile string
	pidfile    string
)

func init() {
	flag.StringVar(&path, "path", "", "path of the file to watch")
	flag.StringVar(&huppidfile, "huppidfile", "", "pidfile for process to signal")
	flag.StringVar(&pidfile, "pidfile", "", "my pidfile")
}

func main() {
	log.SetFlags(0)
	flag.Parse()

	if path == "" {
		log.Fatal("watch path not set")
	}

	if huppidfile == "" {
		log.Fatal("huppidfile not set")
	}

	if pidfile != "" {
		pid := os.Getpid()
		pidbytes := []byte(strconv.Itoa(pid))
		_ = ioutil.WriteFile(pidfile, pidbytes, 0644)
	}

	watch, err := os.Open(path)
	if err != nil {
		log.Fatalln("Failed to open file", path, err)
	}
	// 43 bytes is the record size of the watch
	buf := make([]byte, 43)
	// initial state
	_, err = watch.Read(buf)
	if err != nil && err != io.EOF {
		log.Fatalln("Error reading watch file", err)
	}
	for {
		_, err := watch.Read(buf)
		if err != nil && err != io.EOF {
			log.Fatalln("Error reading watch file", err)
		}
		if err == io.EOF {
			continue
		}
		// a few changes eg debug do not require a daemon restart
		// however at present we cannot check changes, and most do
		restart := true
		if restart {
			cmd := exec.Command("service", "docker", "restart")
			// not much we can do if it does not restart
			_ = cmd.Run()
		} else {
			bytes, err := ioutil.ReadFile(huppidfile)
			if err != nil {
				continue
			}
			pidstring := string(bytes[:])
			pid, err := strconv.Atoi(pidstring)
			if err != nil {
				continue
			}
			syscall.Kill(pid, syscall.SIGHUP)
		}
	}
}
