package settings

import (
	"errors"
	"fmt"
	"os"
	"reflect"
	"slices"

	"github.com/caarlos0/env/v11"
	"github.com/joho/godotenv"
	"github.com/spf13/pflag"

	"buffersnow.com/spiritonline/pkg/util"
	"buffersnow.com/spiritonline/pkg/version"
)

var fs *pflag.FlagSet

func (o *Options) loadArgs(ver *version.BuildTag) error {

	fs = pflag.NewFlagSet("", pflag.ContinueOnError)
	fs.Usage = func() {
		fmt.Printf("Usage: ./%s{.exe/.lxb} <... arguments>\n", ver.GetService())
		o.helpText()
		fmt.Printf("\nThis help menu can be brought up again by running \"./%s{.exe/.lxb} help\"\n", ver.GetService())
		os.Exit(0)
	}

	if err := o.parseOptions(reflect.ValueOf(o), "", ""); err != nil {
		return fmt.Errorf("settings: parser: %w", err)
	}

	if slices.Contains(os.Args[1:], "help") ||
		slices.Contains(os.Args[1:], "-h") ||
		slices.Contains(os.Args[1:], "--help") {

		fs.Usage()
	}

	filtered := slices.DeleteFunc(os.Args[1:], func(s string) bool {
		return s == "--help" || s == "-h" || s == "help"
	})

	err := fs.Parse(filtered)
	if err != nil && err != pflag.ErrHelp {
		return fmt.Errorf("settings: %w", err)
	} else if err == pflag.ErrHelp {
		fs.Usage()
	}

	o.Runtime.LogArchival = !o.Runtime.LogArchival

	if o.DeploymentOverride.EnableOverride {
		o.Spirit.AuthorizationToken = o.DeploymentOverride.AuthorizationToken
		o.Spirit.ServiceTag = o.DeploymentOverride.ServiceTag
	}

	if len(o.Service.Ports) == 0 {
		return errors.New("settings: no ports were defined in the configuration")
	}

	return nil
}

func (o *Options) loadEnv() error {

	if err := godotenv.Load(); err != nil {
		//% the only error thrown is from os.Open in godotenv.go L#207
		return fmt.Errorf("settings: env: os: %w", err)
	}

	//& cleanup service_ports and service_features
	tasks := []func() error{
		func() error { return util.CleanEnv("SERVICE_PORTS") },
		func() error { return util.CleanEnv("SERVICE_FEATURES") },
		func() error { return util.CleanEnv("SERVICE_HTTP_PROXIES") },
	}

	if err := util.Batch(tasks); err != nil {
		return fmt.Errorf("settings: util: %w", err)
	}

	var cfg Options
	if err := env.Parse(&cfg); err != nil {
		return fmt.Errorf("settings: %w", err)
	}

	o.MySQL = cfg.MySQL
	o.Spirit = cfg.Spirit
	o.Service = cfg.Service

	return nil
}
