package main // import "amuz.es/src/infra/cpu_ctrl"

import (
	"time"
	"context"
	"os"
	"fmt"
	"go.uber.org/zap"
	"gopkg.in/alecthomas/kingpin.v2"
	"runtime"
	"amuz.es/src/infra/goutils/handler"
)

const (
	name = "cpu_ctrl"
)

// command argument
var (
	// 아래 부분은 컴파일시 하드코딩됨
	buildDate, version string

	app      = kingpin.New(name, fmt.Sprintf("%s -  metric collector", name)).Author("Amazing from here")
	P        = app.Flag("proportional-gain", "Set proportional gain value.").Short('p').Default("1.0").Float64()
	I        = app.Flag("integral-gain", "Set integral gain value.").Short('i').Default("0.4").Float64()
	D        = app.Flag("derivative-gain", "Set derivative gain value.").Short('d').Default("2.0").Float64()
	SetPoint = app.Flag("set-point", "Set pointe tempeture").Short('t').Default("40.0").Float64()
	SampleInterval = app.Flag("interval", "Set sampling interval").Short('s').Default("1s").Duration()
	InfluxHost = app.Flag("influx-host", "Set influx host").Short('h').Default("db:8089").TCP()
	verbose  = app.Flag("verbose", "Enable verbose mode.").Short('v').Bool()

	// 아래 부분은 실행될때 평가됨
	start = time.Now().Local()

	logger = zap.L().Sugar()
)

func init() {
	defer finalCloser()

	runtime.GOMAXPROCS(2)

	// command 설정 로드
	app.Version(version)
	if _, err := app.Parse(os.Args[1:]); err != nil {
		fmt.Fprintln(os.Stderr, err.(error).Error())
		os.Exit(1)
	}
}

// 엔트리 포인트
func main() {
	defer finalCloser()

	// 로그 초기화
	loggerCleanup := initLogger()
	defer loggerCleanup()

	// 컨텍스트 생성
	// handler내부에서도 로거를 이용하기 때문에 로깅부분 밑에 위치해야 된다.
	mainHandler := handler.NewHandler(context.Background())

	// hello ;-)
	logger.Infof(
		"%s(%s), built: %s",
		name,
		version,
		buildDate,
	)

	// 컨텍스트 띄우기
	processorCleanup := initProcessor(mainHandler)
	defer processorCleanup()

	// 뭔가 문제가 나거나 signal이 발생할 때 까지 애플리케이션이 종료로 빠지지 않게 잡아주는 부분
	contextWatcher, contextCloser := initContext(mainHandler)
	defer contextCloser()

	// ok
	logger.Info("bootstrapped application ", time.Since(start), " ", time.Now())
	contextWatcher()
	logger.Info("served duration: ", time.Since(start))
}

