package main

import (
	"os"
	"path/filepath"
	"time"

	"github.com/kkyr/fig"
	"github.com/rs/zerolog"
)

var defaultConfig = `# All values in this config file WILL BE overwritten by ENV variables (GI_SERVER_PORT for example) if they exist.
Server:
  port: 3500
  locationPhotoDir: "./app/photos/locations/"

Logger:
  loglevel: "debug" # debug/info/warn/error
  loggingFile: "./app/log/goInventorize.log"

Authentication:
  BasicAuth: true
  UserName: "admin"
  Password: "password"

TZ: "America/New_York" # For goinventorize TZ, TZ in UNDERLYING docker image (scratch) is not set
Development: false
`

type Config struct {
	Timezone string `fig:"tz" default:"America/New_York"`
	Server   struct {
		Port             string `fig:"port" default:"3000"`
		LocationPhotoDir string `fig:"locationPhotoDir" default:"./app/photos/locations/"`
	}
	Logger struct {
		Level       string `fig:"loglevel" default:"info"`
		LoggingFile string `fig:"loggingFile" default:"./app/log/goInventorize.log"`
	}
	Authentication struct {
		BasicAuth bool   `fig:"basicauth"`
		UserName  string `fig:"username" default:"admin"`
		Password  string `fig:"password" default:"password"`
	}

	Development bool `fig:"development"` // Cannot set default for BOOL will default to false if nothing supplied
}

func LoadConfig(s *Server) error {
	var cfg Config
	// Create our app folder structure in case it does not exist
	err := os.MkdirAll("./app/config", 0755)
	if err != nil {
		return err
	}
	err = os.MkdirAll("./app/database", 0755)
	if err != nil {
		return err
	}
	// If config file not exist, create it
	if _, err := os.Stat("./app/config/config.yaml"); os.IsNotExist(err) {
		// Write our config to a file
		err := os.WriteFile("./app/config/config.yaml", []byte(defaultConfig), 0755)
		if err != nil {
			return err
		}
	}

	err = fig.Load(&cfg, fig.File("config.yaml"), fig.Dirs("./app/config"), fig.UseEnv("GI")) // Load in config.yaml, then overwrite with ENV variables prefixed with GI
	if err != nil {
		return err
	}
	// Create our logging dir
	err = os.MkdirAll(filepath.Dir(cfg.Logger.LoggingFile), 0755)
	if err != nil {
		return err
	}
	// Create our logging file
	logFile, err := os.OpenFile(cfg.Logger.LoggingFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) // Open/Create log file for writting to log
	if err != nil {
		return err
	}
	switch cfg.Logger.Level { // Setting our logging level
	case "error":
		zerolog.SetGlobalLevel(zerolog.ErrorLevel)
	case "warn":
		zerolog.SetGlobalLevel(zerolog.WarnLevel)
	case "debug":
		zerolog.SetGlobalLevel(zerolog.DebugLevel)
	default:
		zerolog.SetGlobalLevel(zerolog.InfoLevel)

	}
	loc, err := time.LoadLocation(cfg.Timezone) // Getting our timezone info from config
	if err != nil {
		return err
	}
	s.LogFile = logFile
	zerolog.TimestampFunc = func() time.Time { // Making sure our logger writes in the correct tz
		return time.Now().In(loc)
	}
	s.Log = zerolog.New(logFile).With().Timestamp().Logger()
	// Creating photo directory
	err = os.MkdirAll(cfg.Server.LocationPhotoDir, 0755)
	if err != nil {
		return err
	}

	s.Log.Info().Msg("Configuration loaded successfully...")
	s.Log.Debug().Msgf("%+v", cfg)
	s.Config = &cfg
	return nil
}
