package main

// import (
// 	"errors"
// 	"os"
// 	"path/filepath"
// 	"regexp"
// 	"slices"
// 	"strings"

// 	"github.com/google/uuid"
// 	"github.com/gookit/goutil/dump"
// 	"github.com/spf13/viper"
// )

// // var routeRulesNames = []string{"Host", "Path", "PathPrefix"}
// const DEFAULT_CONFIG_PATH = "./z/config"
// const DEFAULT_CONFIG_TYPE = "yaml"
// const DEFAULT_CONFIG_NAME = "config"

// var config = ConfigBuild()

// type Config struct {
// 	Routers     Routers
// 	Services    Services
// 	EntryPoints EntryPoints
// 	TLS         TLS
// 	AuthMap     AuthMap
// 	Health      *Health
// 	Logs        *Logs
// }
// type Logs struct {
// 	ConfigBuild []string
// }
// type Health struct {
// 	ConfigHealth *ConfigHealth
// }
// type ConfigHealth struct {
// 	Routers     bool
// 	Services    bool
// 	EntryPoints bool
// 	AuthBuild   bool
// }
// type ConfigLog map[string][]string

// type AuthMap map[string]*Auth
// type Auth struct {
// 	SessionSecret string
// 	Paths         *Paths
// 	OpenID        *OpenID
// }
// type OpenID struct {
// 	Realm                 string
// 	Issuer                string
// 	ClientID              string
// 	ClientSecret          string
// 	AuthURL               string
// 	TokenURL              string
// 	UserURL               string
// 	LogoutURL             string
// 	Config                string
// 	RedirectURI           string
// 	PostLogoutRedirectUri string
// }
// type Paths struct {
// 	Prefix   string
// 	Login    string
// 	Logout   string
// 	Callback string
// }
// type EntryPoints map[string]*EntryPoint
// type EntryPoint struct {
// 	Address string
// 	TLS     *EntryPointTLS
// }
// type EntryPointTLS struct {
// 	Enabled bool
// }
// type TLS struct {
// 	CertProviders CertProviders
// }
// type CertProviders map[string]*certProvider
// type certProvider struct {
// 	Cert string
// 	Key  string
// }
// type Routers map[string]*Router

// type Router struct {
// 	Priority   int
// 	Name       string
// 	Service    string
// 	EntryPoint string
// 	Routes     Routes
// 	Auth       RouterAuth
// }
// type RouterAuth struct {
// 	Enabled  bool
// 	Provider string
// }
// type Routes map[string]*Route

// type Route struct {
// 	ID     string
// 	Router string
// 	Rule   map[string]string
// }

// type Services map[string]string

// func (e EntryPoints) ForEach(fn func(name string, data *EntryPoint)) {
// 	for name, data := range e {
// 		fn(name, data)
// 	}
// }
// func (r Routers) ForEach(fn func(name string, data *Router) string) {

// 	for name, data := range r {
// 		msg := fn(name, data)
// 		if msg == "break" {
// 			break
// 		}
// 		if msg == "continue" {
// 			continue
// 		}
// 	}
// }
// func (r Routers) ForEachByPriority(fn func(name string, data *Router)) {
// 	slc := r.getSlicesByPriority()
// 	for _, n := range slc {
// 		d := r[n]
// 		fn(n, d)
// 	}
// }
// func (r Routers) getSlicesByPriority() []string {

// 	routersSlice := []string{}
// 	r.ForEach(func(routerName string, routerData *Router) string {
// 		routersSlice = append(routersSlice, routerName)
// 		return ""
// 	})
// 	slices.SortFunc(routersSlice, func(a, b string) int {
// 		if r[a].Priority == r[b].Priority {
// 			return 0
// 		}
// 		if r[a].Priority > r[b].Priority {
// 			return -1
// 		}
// 		if r[a].Priority < r[b].Priority {
// 			return 1
// 		}
// 		return r[a].Priority - r[b].Priority
// 	})
// 	return routersSlice

// }
// func (r *Router) GetRouteByID(routeID string) *Route {
// 	return r.Routes[routeID]
// }
// func (r Routes) ForEach(fn func(routeID string, v *Route) string) {

// 	for routeID, v := range r {
// 		msg := fn(routeID, v)
// 		if msg == "break" {
// 			break
// 		}
// 		if msg == "continue" {
// 			continue
// 		}
// 	}
// }
// func (r Route) ForEachRule(fn func(routeID string, ruleName string, ruleValue string)) {
// 	for k, v := range r.Rule {
// 		fn(r.ID, k, v)
// 	}
// }
// func InitConfigStruct() *Config {
// 	config := &Config{
// 		Routers:     Routers{},
// 		Services:    Services{},
// 		EntryPoints: EntryPoints{},
// 		TLS: TLS{
// 			CertProviders: CertProviders{},
// 		},
// 		AuthMap: AuthMap{},
// 		Health: &Health{
// 			ConfigHealth: &ConfigHealth{
// 				Routers:     false,
// 				Services:    false,
// 				EntryPoints: false,
// 				AuthBuild:   false,
// 			},
// 		},
// 		Logs: &Logs{
// 			ConfigBuild: []string{},
// 		},
// 	}

// 	return config
// }
// func ConfigBuild() *Config {
// 	viperConfig := NewViperConfig()
// 	config := InitConfigStruct()
// 	// //Routers
// 	// //Services
// 	BuildRoutersConfig(viperConfig, config, "routers")
// 	BuildServicesConfig(viperConfig, config, "services")
// 	BuildEntryPointsConfig(viperConfig, config, "entrypoints")
// 	BuildCertProvidersConfig(viperConfig, config, "tls.certproviders")
// 	BuildAuthConfig(viperConfig, config, "auth")

// 	// if !BuildServicesConfig(viperConfig, config, "services") {
// 	// 	err = errors.Join(errors.New("build services config error ="))
// 	// }
// 	// if !BuildRoutersConfig(viperConfig, config, "routers") {
// 	// 	err = errors.Join(errors.New("build routers config error"))
// 	// }

// 	// // //Entrypoints
// 	// if !BuildEntryPointsConfig(viperConfig, config, "entryPoints") {
// 	// 	err = errors.Join(errors.New("build entry points config error"))
// 	// }
// 	// // //TLS Certificate Providers
// 	// if !BuildCertProvidersConfig(viperConfig, config, "tls.certproviders") {
// 	// 	err = errors.Join(errors.New("build cert providers config error"))
// 	// }
// 	// if !BuildAuthConfig(viperConfig, config, "auth") {
// 	// 	// err = errors.Join(errors.New("build auth config error"))
// 	// }
// 	return config
// }

// func BuildCertProvidersConfig(viperConfig *viper.Viper, config *Config, key string) bool {
// 	if viperConfig.Sub(key) == nil {
// 		config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
// 		return false
// 	} else {
// 		certProviders := viperConfig.Sub(key).AllSettings()

// 		// config.TLS.CertProviders = make(CertProviders)
// 		for k, v := range certProviders {
// 			v := v.(map[string]any)
// 			cert := v["cert"].(string)
// 			key := v["key"].(string)
// 			config.TLS.CertProviders[k] = &certProvider{
// 				Cert: cert,
// 				Key:  key,
// 			}
// 		}
// 		return true
// 	}
// }
// func BuildServicesConfig(viperConfig *viper.Viper, config *Config, key string) bool {
// 	if viperConfig.Sub(key) == nil {

// 		config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
// 		dump.P("Missing \"" + key + "\" in Config")
// 		return false
// 	} else {
// 		config.Services = make(Services)
// 		services := viperConfig.Sub(key).AllSettings()
// 		for k, v := range services {
// 			config.Services[k] = v.(string)
// 		}
// 		return true
// 	}
// }
// func BuildEntryPointsConfig(viperConfig *viper.Viper, config *Config, key string) bool {
// 	if viperConfig.Sub(key) == nil {
// 		config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
// 		dump.P("Missing \"" + key + "\" in Config")

// 		return false
// 	} else {
// 		entryPoints := viperConfig.Sub(key).AllSettings()
// 		for k, v := range entryPoints {

// 			entryPoint := &EntryPoint{
// 				Address: "",
// 				TLS: &EntryPointTLS{
// 					Enabled: false,
// 				},
// 			}
// 			v := v.(map[string]any)

// 			if _, ok := v["address"]; ok {
// 				entryPoint.Address = v["address"].(string)
// 			}
// 			if _, ok := v["tls"]; ok {
// 				tls := v["tls"].(map[string]any)
// 				enabled := tls["enabled"].(bool)
// 				entryPoint.TLS = &EntryPointTLS{
// 					Enabled: enabled,
// 				}
// 			}

// 			config.EntryPoints[k] = entryPoint
// 		}
// 		return true
// 	}
// }
// func BuildAuthConfig(viperConfig *viper.Viper, config *Config, key string) bool {
// 	if viperConfig.Sub(key) == nil {
// 		config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
// 		dump.P("Missing \"" + key + "\" in Config")

// 		return false
// 	} else {
// 		auth := viperConfig.Sub(key).AllSettings()
// 		for k, v := range auth {
// 			paths := v.(map[string]any)["paths"].(map[string]any)
// 			openID := v.(map[string]any)["openid"].(map[string]any)
// 			sessionSecret := v.(map[string]any)["sessionsecret"].(string)

// 			config.AuthMap[k] = &Auth{
// 				SessionSecret: sessionSecret,
// 				Paths: &Paths{
// 					Prefix:   paths["prefix"].(string),
// 					Login:    paths["login"].(string),
// 					Logout:   paths["logout"].(string),
// 					Callback: paths["callback"].(string),
// 				},
// 				OpenID: &OpenID{
// 					Realm:                 openID["realm"].(string),
// 					Issuer:                openID["issuer"].(string),
// 					ClientID:              openID["client_id"].(string),
// 					ClientSecret:          openID["client_secret"].(string),
// 					RedirectURI:           openID["redirect_uri"].(string),
// 					PostLogoutRedirectUri: openID["post_logout_redirect_uri"].(string),
// 					Config:                openID["config"].(string),
// 					AuthURL:               openID["authurl"].(string),
// 					TokenURL:              openID["tokenurl"].(string),
// 					UserURL:               openID["userurl"].(string),
// 					LogoutURL:             openID["logouturl"].(string),
// 				},
// 			}
// 		}
// 		return true
// 	}
// }
// func splitStatementByRegex(str string, regx string) []string {

// 	input := str
// 	re := regexp.MustCompile(regx)
// 	matches := re.FindAllStringSubmatch(input, -1)
// 	if len(matches) == 0 {
// 		return []string{str} // Return original if no backticks found
// 	}

// 	result := []string{}
// 	lastIndex := 0

// 	for _, match := range matches {

// 		startIndex := strings.Index(input, match[0])

// 		if startIndex > lastIndex {
// 			str := input[lastIndex:startIndex]
// 			str, _ = strings.CutPrefix(str, ".")
// 			result = append(result, str)
// 		}
// 		str := match[1]
// 		str, _ = strings.CutPrefix(str, ".")
// 		result = append(result, str) // Append the content within backticks
// 		lastIndex = startIndex + len(match[0])
// 	}

// 	if lastIndex < len(input) {
// 		str := input[lastIndex:]
// 		str, _ = strings.CutPrefix(str, ".")
// 		result = append(result, str)
// 	}

// 	return result
// }
// func BuildRoutersConfig(viperConfig *viper.Viper, config *Config, key string) bool {
// 	if viperConfig.Sub(key) == nil {
// 		config.Logs.ConfigBuild = append(config.Logs.ConfigBuild, "Missing \""+key+"\" in Config")
// 		dump.P("Missing \"" + key + "\" in Config")
// 		return false
// 	} else {
// 		routers := viperConfig.Sub(key).AllSettings()
// 		for routerName, d := range routers {
// 			data := d.(map[string]any)
// 			if _, ok := data["routes"]; !ok {
// 				continue
// 			}
// 			if _, ok := data["service"]; !ok {
// 				continue
// 			}
// 			if _, ok := data["entrypoint"]; !ok {
// 				continue
// 			}
// 			if _, ok := data["priority"]; !ok {
// 				data["priority"] = 1000
// 			}
// 			if _, ok := data["routes"]; !ok {
// 				continue
// 			}
// 			routes := data["routes"].([]any)
// 			service := data["service"].(string)
// 			entryPoint := data["entrypoint"].(string)
// 			priority := data["priority"].(int)

// 			enabled := false
// 			provider := ""
// 			if _, ok := data["auth"]; ok {
// 				enabled = data["auth"].(map[string]any)["enabled"].(bool)
// 				provider = data["auth"].(map[string]any)["provider"].(string)
// 			}

// 			router := &Router{
// 				Name:       routerName,
// 				Priority:   priority,
// 				Service:    service,
// 				EntryPoint: entryPoint,
// 				Routes:     Routes{},
// 				Auth: RouterAuth{
// 					Enabled:  enabled,
// 					Provider: provider,
// 				},
// 			}

// 			for _, v := range routes {
// 				routeID := uuid.New().String()
// 				route := &Route{
// 					ID:     routeID,
// 					Router: routerName,
// 					Rule:   map[string]string{},
// 				}
// 				rawRoute := v.(string)
// 				route.Rule["raw"] = rawRoute

// 				routeStatmentsSlice := splitStatementByRegex(rawRoute, "\\(`(.*?)`\\)")

// 				for i, v := range routeStatmentsSlice {
// 					if i&1 == 0 {
// 						if i+1 < len(routeStatmentsSlice) {
// 							route.Rule[v] = routeStatmentsSlice[i+1]
// 						}
// 					}
// 				}
// 				// if _, ok := route.Rule["Auth"]; !ok {
// 				// 	route.Rule["Auth"] = ""
// 				// }
// 				router.Routes[routeID] = route

// 				// router.Routes = append(router.Routes, route)
// 			}
// 			config.Routers[routerName] = router

// 		}
// 		return true

// 	}
// }
// func NewViperConfig() *viper.Viper {
// 	vc := viper.New()
// 	vc.AddConfigPath(DEFAULT_CONFIG_PATH)
// 	vc.SetConfigType(DEFAULT_CONFIG_TYPE)
// 	vc.SetConfigName(DEFAULT_CONFIG_NAME)
// 	vc.ReadInConfig()

// 	fileNames, err := getFileNames(DEFAULT_CONFIG_PATH, DEFAULT_CONFIG_NAME)
// 	if err != nil {
// 		dump.Println("No extra config files" + err.Error())
// 	} else {
// 		for _, fileName := range fileNames {
// 			vc.SetConfigName(fileName)
// 			vc.MergeInConfig()
// 			dump.P("TEST")
// 		}
// 	}

// 	return vc
// }
// func getYamlFileNameExcExt(fileName string, exts ...string) (string, error) {
// 	var fileExt string
// 	for _, ext := range exts {
// 		if strings.HasSuffix(fileName, ext) {
// 			fileExt = ext
// 			break
// 		}
// 	}

// 	if name, ok := strings.CutSuffix(fileName, fileExt); ok {
// 		return name, nil
// 	} else {
// 		return "", errors.New("Error: no file extension found!")
// 	}
// }
// func getFileNames(folderPath string, skipFileName string) ([]string, error) {
// 	var fileNames []string

// 	err := filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
// 		if err != nil {
// 			return err
// 		}

// 		if !info.IsDir() { // Only add files, not directories
// 			filename := info.Name()
// 			filesize := info.Size()
// 			filenameNoExt, _ := getYamlFileNameExcExt(filename, ".yaml", ".yml")
// 			if skipFileName == filenameNoExt || filesize == 0 {
// 				return nil
// 			}
// 			fileNames = append(fileNames, filenameNoExt)
// 		}
// 		return nil
// 	})

// 	if err != nil {
// 		return nil, err
// 	}

// 	return fileNames, nil
// }
