package config

import (
	"fmt"
	"gitlab.schukai.com/oss/libraries/go/application/configuration"
	error2 "gitlab.schukai.com/oss/utilities/documentation-manager/error"
	"gitlab.schukai.com/oss/utilities/documentation-manager/logging"
	"gitlab.schukai.com/oss/utilities/documentation-manager/release"
	"os"
	"path"
)

var preparation *configuration.Settings[AppConfig]
var Instance *configuration.Settings[AppConfig]

func SetUp(cfgPath string) {

	preparation = newDefaultConfig()
	preparation.SetMnemonic(release.GetMnemonic())

	if preparation.HasErrors() {
		for _, msg := range preparation.Errors() {
			error2.PrintError(msg.Error())
		}
		error2.CheckError(fmt.Errorf("configuration errors"))
	}

	if cfgPath != "" {
		if !path.IsAbs(cfgPath) {
			c, err := os.Getwd()
			error2.CheckError(err)
			cfgPath = path.Clean(path.Join(c, cfgPath))
		}

		preparation.AddFile(cfgPath)
	} else {
		preparation.SetDefaultDirectories()
	}

	//wait := make(chan bool)

	Instance = newDefaultConfig()

	//var once configuration.ChangeHook
	//once = &configuration.ChangeEventHandler{
	//	Callback: func(event configuration.ChangeEvent) {
	//		if !checkConstraints() {
	//			error2.PrintErrorAndExit("Configuration contains errors and was not overwritten. Check your configuration and the logs why this might have happened.")
	//		}
	//
	//		Instance.SetConfig(preparation.Config())
	//
	//		wait <- true
	//
	//	},
	//}
	//
	//preparation.OnChange(once)
	preparation.Import()

	if preparation.HasErrors() {
		for _, msg := range preparation.Errors() {
			error2.PrintError(msg.Error())
		}
		//		error2.CheckError(fmt.Errorf("configuration errors"))
	}

	//select {
	//case <-wait:
	//	preparation.RemoveOnChangeHook(once)
	//	initRuntimeHook()
	//	close(wait)
	//case <-time.After(time.Second * 2):
	//	error2.PrintErrorAndExit("configuration could not be loaded in time")
	//}
	//
	//logging.LogInfo("load configuration")

}

func initRuntimeHook() {

	var h configuration.ChangeHook
	h = &configuration.ChangeEventHandler{
		Callback: func(event configuration.ChangeEvent) {
			if checkConstraints() {
				Instance.SetConfig(preparation.Config())
				if Instance.HasErrors() {
					for _, msg := range Instance.Errors() {
						logging.LogError(msg.Error())
					}
					Instance.ResetErrors()
				}

			} else {
				logging.LogError("Configuration contains errors and was not overwritten. Check your configuration and the logs why this might have happened.")
			}

		},
	}

	var e configuration.ErrorHook
	e = &configuration.ErrorEventHandler{
		Callback: func(event configuration.ErrorEvent) {

			for _, msg := range Instance.Errors() {
				logging.LogError(msg.Error())
			}
		},
	}

	preparation.InitFromEnv(release.GetMnemonic())
	Instance.SetConfig(preparation.Config())
	if Instance.HasErrors() {
		for _, msg := range Instance.Errors() {
			logging.LogError(msg.Error())
		}
		Instance.ResetErrors()
	}

	preparation.OnChange(h).OnError(e)

	preparation.Watch()

}