package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"path"
	"syscall"
	"time"

	lfcc "git.loafle.net/commons_go/config"
	"git.loafle.net/commons_go/logging"
	oocc "git.loafle.net/overflow/overflow_commons_go/config"
	ooccp "git.loafle.net/overflow/overflow_commons_go/config/probe"
	oocmci "git.loafle.net/overflow/overflow_commons_go/modules/commons/interfaces"
	"git.loafle.net/overflow/overflow_probes/auth"
	"git.loafle.net/overflow/overflow_probes/config"
	"git.loafle.net/overflow/overflow_probes/probe"
)

/*
/bin/
	probe.exe
/config/
	/sensor/
	noauthprobe.json
	central.json
	probe.json
	logging.json

*/

// const (
// 	// name of the service
// 	serviceName        = "Probe"
// 	serviceDescription = "Probe Service of overFlow"
// )

var (
	configDir *string
)

func init() {
	// flag.Usage = func() {
	// 	fmt.Printf("Usage of %s\n", os.Args[0])
	// 	fmt.Printf("  [install | remove | start | stop | status]\n")
	// 	flag.PrintDefaults()
	// }

	configDir = oocc.FlagConfigDir("./")
	flag.Parse()

	logging.InitializeLogger("")
}

func main() {
	defer logging.Logger().Sync()

	printBanner()
	loadConfig()

	var instance interface{}

	go func() {
		if ooccp.ProbeStateTypeNotAuthorized == config.Config.Probe.State() {
			var err error
			instance = auth.New()

			authDoneChan := make(chan error, 1)
			defer close(authDoneChan)

			if err := instance.(oocmci.EndableStarter).EndableStart(authDoneChan); err != nil {
				logging.Logger().Error(err)
				os.Exit(1)
			}
			err = <-authDoneChan
			if nil != err {
				logging.Logger().Error(err)
				os.Exit(1)
			}
		}
		instance = probe.New()
		if err := instance.(oocmci.Starter).Start(); err != nil {
			logging.Logger().Error(err)
			os.Exit(1)
		}

	}()

	// // Set up channel on which to send signal notifications.
	// // We must use a buffered channel or risk missing the signal
	// // if we're not ready to receive when the signal is sent.
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt,
		syscall.SIGKILL,
		syscall.SIGSTOP,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)

	<-interrupt
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := instance.(oocmci.Stopper).Stop(ctx); err != nil {
		logging.Logger().Errorf("Probe error: %v", err)
	}

}

func loadConfig() {
	if dir, err := lfcc.ABSPathify(*configDir); nil != err {
		logging.Logger().Panicf("Config path[%s] is not valid", *configDir)
	} else {
		logging.Logger().Debugf("Config path: %s", dir)
		config.ConfigDir = &dir
	}
	cfp := path.Join(*config.ConfigDir, ooccp.ConfigFileName)
	config.ConfigFilePath = &cfp

	conf := lfcc.New()
	config.Config = &ooccp.Config{}
	if err := conf.Load(config.Config, *config.ConfigFilePath); nil != err {
		logging.Logger().Panicf("Config is not valid: %v", err)
	}
}

const (
	version = "1.0.0"
	website = "https://www.overflow.cloud"
	banner  = `

 ██████╗ ██╗   ██╗███████╗██████╗ ███████╗██╗      ██████╗ ██╗    ██╗
██╔═══██╗██║   ██║██╔════╝██╔══██╗██╔════╝██║     ██╔═══██╗██║    ██║
██║   ██║██║   ██║█████╗  ██████╔╝█████╗  ██║     ██║   ██║██║ █╗ ██║
██║   ██║╚██╗ ██╔╝██╔══╝  ██╔══██╗██╔══╝  ██║     ██║   ██║██║███╗██║
╚██████╔╝ ╚████╔╝ ███████╗██║  ██║██║     ███████╗╚██████╔╝╚███╔███╔╝
 ╚═════╝   ╚═══╝  ╚══════╝╚═╝  ╚═╝╚═╝     ╚══════╝ ╚═════╝  ╚══╝╚══╝

`
)

func printBanner() {
	fmt.Println(banner)
	fmt.Printf("Version: %s\n", version)
	fmt.Printf("URL: %s\n", website)
	fmt.Println()

}
