package installer

import (
	"fmt"
	"html/template"
	"strings"
)

type Release struct {
	AppInstanceId string `json:"appInstanceId"`
	Namespace     string `json:"namespace"`
	RepoAddr      string `json:"repoAddr"`
	AppDir        string `json:"appDir"`
	ImageRegistry string `json:"imageRegistry,omitempty"`
}

type Network struct {
	Name               string `json:"name,omitempty"`
	IngressClass       string `json:"ingressClass,omitempty"`
	CertificateIssuer  string `json:"certificateIssuer,omitempty"`
	Domain             string `json:"domain,omitempty"`
	AllocatePortAddr   string `json:"allocatePortAddr,omitempty"`
	ReservePortAddr    string `json:"reservePortAddr,omitempty"`
	DeallocatePortAddr string `json:"deallocatePortAddr,omitempty"`
}

type InfraAppInstanceConfig struct {
	Id      string         `json:"id"`
	AppId   string         `json:"appId"`
	Infra   InfraConfig    `json:"infra"`
	Release Release        `json:"release"`
	Values  map[string]any `json:"values"`
	Input   map[string]any `json:"input"`
	URL     string         `json:"url"`
	Help    []HelpDocument `json:"help"`
	Icon    template.HTML  `json:"icon"`
}

type AppInstanceConfig struct {
	Id      string         `json:"id"`
	AppId   string         `json:"appId"`
	Env     EnvConfig      `json:"env"`
	Release Release        `json:"release"`
	Values  map[string]any `json:"values"`
	Input   map[string]any `json:"input"`
	URL     string         `json:"url"`
	Help    []HelpDocument `json:"help"`
	Icon    string         `json:"icon"`
}

func (a AppInstanceConfig) InputToValues(schema Schema) map[string]any {
	ret, err := derivedToConfig(a.Input, schema)
	if err != nil {
		panic(err)
	}
	return ret
}

func getField(v any, f string) any {
	for _, i := range strings.Split(f, ".") {
		vm := v.(map[string]any)
		v = vm[i]
	}
	return v
}

func deriveValues(
	root any,
	values any,
	schema Schema,
	networks []Network,
	vpnKeyGen VPNAPIClient,
) (map[string]any, error) {
	ret := make(map[string]any)
	for _, f := range schema.Fields() {
		k := f.Name
		def := f.Schema
		// TODO(gio): validate that it is map
		v, ok := values.(map[string]any)[k]
		// TODO(gio): if missing use default value
		if !ok {
			if def.Kind() == KindSSHKey {
				key, err := NewECDSASSHKeyPair("tmp")
				if err != nil {
					return nil, err
				}
				ret[k] = map[string]string{
					"public":  string(key.RawAuthorizedKey()),
					"private": string(key.RawPrivateKey()),
				}
			}
			if def.Kind() == KindVPNAuthKey {
				enabled := true
				if v, ok := def.Meta()["enabledField"]; ok {
					// TODO(gio): Improve getField
					enabled, ok = getField(root, v).(bool)
					if !ok {
						return nil, fmt.Errorf("could not resolve enabled: %+v %s %+v", def.Meta(), v, root)
					}
				}
				if !enabled {
					continue
				}
				var username string
				if v, ok := def.Meta()["username"]; ok {
					username = v
				} else if v, ok := def.Meta()["usernameField"]; ok {
					// TODO(gio): Improve getField
					username, ok = getField(root, v).(string)
					if !ok {
						return nil, fmt.Errorf("could not resolve username: %+v %s %+v", def.Meta(), v, root)
					}
				}
				authKey, err := vpnKeyGen.GenerateAuthKey(username)
				if err != nil {
					return nil, err
				}
				ret[k] = authKey
			}
			continue
		}
		switch def.Kind() {
		case KindBoolean:
			ret[k] = v
		case KindString:
			ret[k] = v
		case KindInt:
			ret[k] = v
		case KindPort:
			ret[k] = v
		case KindVPNAuthKey:
			ret[k] = v
		case KindArrayString:
			a, ok := v.([]string)
			if !ok {
				return nil, fmt.Errorf("expected string array")
			}
			ret[k] = a
		case KindNetwork:
			name, ok := v.(string)
			if !ok {
				return nil, fmt.Errorf("not a string")
			}
			n, err := findNetwork(networks, name)
			if err != nil {
				return nil, err
			}
			ret[k] = n
		case KindMultiNetwork:
			vv, ok := v.([]any)
			if !ok {
				return nil, fmt.Errorf("not an array")
			}
			picked := []Network{}
			for _, nn := range vv {
				name, ok := nn.(string)
				if !ok {
					return nil, fmt.Errorf("not a string")
				}
				n, err := findNetwork(networks, name)
				if err != nil {
					return nil, err
				}
				picked = append(picked, n)
			}
			ret[k] = picked
		case KindAuth:
			r, err := deriveValues(root, v, AuthSchema, networks, vpnKeyGen)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindSSHKey:
			r, err := deriveValues(root, v, SSHKeySchema, networks, vpnKeyGen)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindStruct:
			r, err := deriveValues(root, v, def, networks, vpnKeyGen)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		default:
			return nil, fmt.Errorf("Should not reach!")
		}
	}
	return ret, nil
}

func derivedToConfig(derived map[string]any, schema Schema) (map[string]any, error) {
	ret := make(map[string]any)
	for _, f := range schema.Fields() {
		k := f.Name
		def := f.Schema
		v, ok := derived[k]
		// TODO(gio): if missing use default value
		if !ok {
			continue
		}
		switch def.Kind() {
		case KindBoolean:
			ret[k] = v
		case KindString:
			ret[k] = v
		case KindInt:
			ret[k] = v
		case KindPort:
			ret[k] = v
		case KindVPNAuthKey:
			ret[k] = v
		case KindArrayString:
			a, ok := v.([]string)
			if !ok {
				return nil, fmt.Errorf("expected string array")
			}
			ret[k] = a
		case KindNetwork:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			name, ok := vm["name"]
			if !ok {
				return nil, fmt.Errorf("expected network name")
			}
			ret[k] = name
		case KindMultiNetwork:
			nl, ok := v.([]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			names := []string{}
			for _, n := range nl {
				i, ok := n.(map[string]any)
				if !ok {
					return nil, fmt.Errorf("expected map")
				}
				name, ok := i["name"]
				if !ok {
					return nil, fmt.Errorf("expected network name")
				}
				names = append(names, name.(string))
			}
			ret[k] = names
		case KindAuth:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			r, err := derivedToConfig(vm, AuthSchema)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindSSHKey:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			r, err := derivedToConfig(vm, SSHKeySchema)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindStruct:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			r, err := derivedToConfig(vm, def)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		default:
			return nil, fmt.Errorf("Should not reach!")
		}
	}
	return ret, nil
}

func findNetwork(networks []Network, name string) (Network, error) {
	for _, n := range networks {
		if n.Name == name {
			return n, nil
		}
	}
	return Network{}, fmt.Errorf("Network not found: %s", name)
}
