package main

import (
	"fmt"
	"log"
	"os"

	"github.com/knadh/koanf"
	"github.com/knadh/koanf/parsers/toml"
	"github.com/knadh/koanf/providers/confmap"
	"github.com/knadh/koanf/providers/file"
	"github.com/knadh/koanf/providers/posflag"
	flag "github.com/spf13/pflag"

	"git.kemonine.info/PiFrame/ui"
)

const (
	CLI_FLAG_CONFIG_ONLY = "config-ui-only"
)

const (
	CONFIG_FILE_PATH              = "/etc/default/pf.toml"
	CONFIG_KEY_SLIDESHOW_DURATION = "slideshow.duration"
	CONFIG_KEY_HDMI_OFF           = "hdmi.off"
	CONFIG_KEY_HDMI_ON            = "hdmi.on"
	CONFIG_KEY_ALBUMS_ROOT        = "albums.root"
	CONFIG_KEY_ALBUMS_SELECTED    = "albums.selected"
)

const (
	DEFAULT_SLIDESHOW_DURATION = "300s"
	DEFAULT_HDMI_OFF           = "*-*-* 00:00:00"
	DEFAULT_HDMI_ON            = "*-*-* 06:00:00"
	DEFAULT_ALBUMS_ROOT        = "/tank/pictures"
	DEFAULT_ALBUM_SELECTED     = "/"
)

func main() {
	// Command line flag handler
	f := flag.NewFlagSet("piframe", flag.ContinueOnError)
	f.Usage = func() {
		fmt.Println(f.FlagUsages())
		os.Exit(0)
	}
	// Command line flags
	f.Bool(CLI_FLAG_CONFIG_ONLY, false, "Only show the config UI, NOT the slideshow")
	cliFlag := f.Lookup(CLI_FLAG_CONFIG_ONLY)
	if cliFlag != nil {
		cliFlag.NoOptDefVal = "true"
	}
	// Process command line flags into handler
	f.Parse(os.Args[1:])

	// Main config variable
	var pfConfig = koanf.New(".")

	// Setup some defaults
	pfConfig.Load(confmap.Provider(map[string]interface{}{
		CONFIG_KEY_SLIDESHOW_DURATION: DEFAULT_SLIDESHOW_DURATION,
		CONFIG_KEY_HDMI_OFF:           DEFAULT_HDMI_OFF,
		CONFIG_KEY_HDMI_ON:            DEFAULT_HDMI_ON,
		CONFIG_KEY_ALBUMS_ROOT:        DEFAULT_ALBUMS_ROOT,
		CONFIG_KEY_ALBUMS_SELECTED:    []string{DEFAULT_ALBUM_SELECTED},
	}, "."), nil)

	// Bring in /etc/defaults/pf.toml if it exists
	configFileProvider := file.Provider(CONFIG_FILE_PATH)
	_, err := os.Stat(CONFIG_FILE_PATH)
	if err != nil {
		if os.IsNotExist(err) {
			// log.Printf("%s does not exist, USING DEFAULTS", CONFIG_FILE_PATH)
		} else {
			if errConfigFile := pfConfig.Load(configFileProvider, toml.Parser()); errConfigFile != nil {
				log.Fatalf("Error loading config : %s", err)
			}
		}
	}

	// 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
		}

		pfConfig.Load(configFileProvider, toml.Parser())
	})

	// Process command line flags
	if err := pfConfig.Load(posflag.Provider(f, ".", pfConfig), nil); err != nil {
		log.Fatalf("Error loading command line flags : %v", err)
	}

	if !pfConfig.Bool(CLI_FLAG_CONFIG_ONLY) {
		ui.Slideshow()
	}

	ui.ConfigGui()
}
