package main

import (
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	argonFan "git.sungo.io/sungo/argon/fan"

	"git.kemonine.info/PiFrame/config"
	"git.kemonine.info/PiFrame/utils"
)

const (
	BUS     = 1
	ADDRESS = 0x1a
)

func main() {
	// Load the config file
	pfConfig, configFileProvider := config.LoadConfig(false)

	// Watch for config changes and re-load config if needed
	configFileProvider.Watch(func(event interface{}, err error) {
		if err != nil {
			log.Printf("Error setting up watch of config : %s", err)
			return
		}

		// Bail on slideshow if there is a config change so it restarts with updated config
		log.Fatalf("Config file changed! Exiting!")
	})

	// Get the various fan related config options as local variables
	POLL_INTERVAL := pfConfig.String(config.CONFIG_KEY_FAN_POLL_INTERVAL)
	SPEED_FULL_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_100)
	SPEED_SEVENTY_FIVE_PERCENT_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_75)
	SPEED_FIFTY_PERCENT_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_50)
	SPEED_TWENTY_FIVE_PERCENT_TEMP := pfConfig.Float64(config.CONFIG_KEY_FAN_SPEEDS + "." + config.CONFIG_MAP_KEY_FAN_SPEED_25)
	SPEED_MINIMUM := pfConfig.Int(config.CONFIG_KEY_FAN_MIN_SPEED)

	// Setup fan and bail if we can't see it
	fan, err := argonFan.New(ADDRESS, BUS)
	if err != nil {
		log.Fatalf("Error working with fan : %s", err)
	}

	// Safe exit
	defer fan.SafeClose()
	sigc := make(chan os.Signal, 1)
	signal.Notify(
		sigc,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT,
	)
	go func() {
		<-sigc
		fan.SafeClose()
		os.Exit(1)
	}()

	// Control fan speed based on temps via a ticker / timeout
	pollInterval, err := time.ParseDuration(POLL_INTERVAL)
	if err != nil {
		log.Fatalf("Error parsing interval duration : %s", err)
	}
	ticker := time.NewTicker(pollInterval)
	for range ticker.C {
		cpuTemp := utils.GetCPUTemp()
		gpuTemp := utils.GetGPUTemp()

		if cpuTemp >= SPEED_FULL_TEMP || gpuTemp >= SPEED_FULL_TEMP {
			if SPEED_MINIMUM > 100 {
				fan.SetSpeed(SPEED_MINIMUM)
			} else {
				fan.SetSpeed(100)
			}
			continue
		}
		if cpuTemp >= SPEED_SEVENTY_FIVE_PERCENT_TEMP || gpuTemp >= SPEED_SEVENTY_FIVE_PERCENT_TEMP {
			if SPEED_MINIMUM > 75 {
				fan.SetSpeed(SPEED_MINIMUM)
			} else {
				fan.SetSpeed(75)
			}
			continue
		}
		if cpuTemp >= SPEED_FIFTY_PERCENT_TEMP || gpuTemp >= SPEED_FIFTY_PERCENT_TEMP {
			if SPEED_MINIMUM > 50 {
				fan.SetSpeed(SPEED_MINIMUM)
			} else {
				fan.SetSpeed(50)
			}
			continue
		}
		if cpuTemp >= SPEED_TWENTY_FIVE_PERCENT_TEMP || gpuTemp >= SPEED_TWENTY_FIVE_PERCENT_TEMP {
			if SPEED_MINIMUM > 25 {
				fan.SetSpeed(SPEED_MINIMUM)
			} else {
				fan.SetSpeed(25)
			}
			continue
		}
		if cpuTemp < SPEED_TWENTY_FIVE_PERCENT_TEMP || gpuTemp < SPEED_TWENTY_FIVE_PERCENT_TEMP {
			fan.SetSpeed(SPEED_MINIMUM)
			continue
		}
		// We should never get here but...
		// Maxing fan to be on the safe side
		log.Print("pf-fan : This should never happen")
		fan.SetSpeed(100)
	}
}
