package config

import (
	
	
	
	
	
	
	

	
)

type configMap map[string]interface{}

func ( configMap) () []string {
	 := make([]string, 0)
	for  := range  {
		 = append(, )
	}
	return 
}

type Field struct {
	Name        string
	Description string
	Style       string
	Tag         string
}

func ( configMap) ( string) ([]Field, error) {
	if ,  := [];  {
		 := make([]Field, 0)
		 := reflect.TypeOf().Elem()
		 := reflect.ValueOf().Elem()
		for  := 0;  < .NumField(); ++ {
			 := .Field()
			if .Type.Name() != "string" {
				return nil, fmt.Errorf("invalid field type [name: '%v', type: '%v']", .Name, .Type.Name())
			}
			 = append(, Field{.Name, .Tag.Get("description"), .FieldByName(.Name).String(), .Tag.Get("tag")})
		}
		return , nil
	}
	return nil, fmt.Errorf("unknown config: '%v'", )
}

var config = struct {
	Styles configMap
}{
	Styles: make(configMap),
}

func ( string,  interface{}) {
	config.Styles[] = 
}

func () error {
	if  := load("styles", config.Styles);  != nil {
		return 
	}
	return nil
}

func load( string,  configMap) error {
	if ,  := xdg.UserConfigDir();  == nil {
		,  := os.ReadFile(fmt.Sprintf("%v/carapace/%v.json", , ))
		if  != nil {
			if os.IsNotExist() {
				return nil
			}
			return 
		}

		var  map[string]map[string]string
		if  := json.Unmarshal(, &);  != nil {
			return 
		}

		for ,  := range  {
			if ,  := [];  {
				 := reflect.ValueOf().Elem()
				for ,  := range  {
					if  := .FieldByName();  != (reflect.Value{}) {
						.SetString()
					}
				}
			}
		}
	}
	return nil
}

func () []string                   { return config.Styles.Keys() }
func ( string) ([]Field, error) { return config.Styles.Fields() }
func (,  string) error {
	return set("styles", , strings.Replace(, ",", " ", -1))
}

func set(, ,  string) error {
	,  := xdg.UserConfigDir()
	if  != nil {
		return 
	}

	 := fmt.Sprintf("%v/carapace/%v.json", , )
	,  := os.ReadFile()
	if  != nil {
		if !os.IsNotExist() {
			return 
		}
		if  := os.MkdirAll(filepath.Dir(), os.ModePerm);  != nil {
			return 
		}
		 = []byte("{}")
	}

	var  map[string]map[string]string
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	if  := strings.Split(, "."); len() != 2 {
		return errors.New("invalid key")
	} else {
		if ,  := [[0]]; ! {
			[[0]] = make(map[string]string, 0)
		}
		if strings.TrimSpace() == "" {
			delete([[0]], [1])
		} else {
			[[0]][[1]] = 
		}
	}

	,  := json.MarshalIndent(, "", "  ")
	if  != nil {
		return 
	}
	return os.WriteFile(, , os.ModePerm)
}