package installer

import (
	"fmt"
	"strings"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/cuecontext"
)

type Kind int

const (
	KindBoolean      Kind = 0
	KindInt               = 7
	KindString            = 1
	KindStruct            = 2
	KindNetwork           = 3
	KindMultiNetwork      = 10
	KindAuth              = 5
	KindSSHKey            = 6
	KindNumber            = 4
	KindArrayString       = 8
	KindPort              = 9
	KindVPNAuthKey        = 11
)

type Field struct {
	Name   string
	Schema Schema
}

type Schema interface {
	Name() string
	Kind() Kind
	Fields() []Field
	Advanced() bool
	Meta() map[string]string
}

var AuthSchema Schema = structSchema{
	name: "Auth",
	fields: []Field{
		Field{"enabled", basicSchema{"Enabled", KindBoolean, false, nil}},
		Field{"groups", basicSchema{"Groups", KindString, false, nil}},
	},
	advanced: false,
}

var SSHKeySchema Schema = structSchema{
	name: "SSH Key",
	fields: []Field{
		Field{"public", basicSchema{"Public Key", KindString, false, nil}},
		Field{"private", basicSchema{"Private Key", KindString, false, nil}},
	},
	advanced: true,
}

const networkSchema = `
#Network: {
    name: string
	ingressClass: string
	certificateIssuer: string | *""
	domain: string
	allocatePortAddr: string
	reservePortAddr: string
	deallocatePortAddr: string
}

value: { %s }
`

func isNetwork(v cue.Value) bool {
	if v.Value().Kind() != cue.StructKind {
		return false
	}
	s := fmt.Sprintf(networkSchema, fmt.Sprintf("%#v", v))
	c := cuecontext.New()
	u := c.CompileString(s)
	network := u.LookupPath(cue.ParsePath("#Network"))
	vv := u.LookupPath(cue.ParsePath("value"))
	if err := network.Subsume(vv); err == nil {
		return true
	}
	return false
}

const multiNetworkSchema = `
#Network: {
    name: string
	ingressClass: string
	certificateIssuer: string | *""
	domain: string
	allocatePortAddr: string
	reservePortAddr: string
	deallocatePortAddr: string
}

#Networks: [...#Network]

value: %s
`

func isMultiNetwork(v cue.Value) bool {
	if v.Value().IncompleteKind() != cue.ListKind {
		return false
	}
	s := fmt.Sprintf(multiNetworkSchema, fmt.Sprintf("%#v", v))
	c := cuecontext.New()
	u := c.CompileString(s)
	networks := u.LookupPath(cue.ParsePath("#Networks"))
	vv := u.LookupPath(cue.ParsePath("value"))
	if err := networks.Subsume(vv); err == nil {
		return true
	}
	return false
}

const authSchema = `
#Auth: {
    enabled: bool | false
    groups: string | *""
}

value: { %s }
`

func isAuth(v cue.Value) bool {
	if v.Value().Kind() != cue.StructKind {
		return false
	}
	s := fmt.Sprintf(authSchema, fmt.Sprintf("%#v", v))
	c := cuecontext.New()
	u := c.CompileString(s)
	auth := u.LookupPath(cue.ParsePath("#Auth"))
	vv := u.LookupPath(cue.ParsePath("value"))
	if err := auth.Subsume(vv); err == nil {
		return true
	}
	return false
}

const sshKeySchema = `
#SSHKey: {
    public: string
    private: string
}

value: { %s }
`

func isSSHKey(v cue.Value) bool {
	if v.Value().Kind() != cue.StructKind {
		return false
	}
	s := fmt.Sprintf(sshKeySchema, fmt.Sprintf("%#v", v))
	c := cuecontext.New()
	u := c.CompileString(s)
	sshKey := u.LookupPath(cue.ParsePath("#SSHKey"))
	vv := u.LookupPath(cue.ParsePath("value"))
	if err := sshKey.Subsume(vv); err == nil {
		return true
	}
	return false
}

type basicSchema struct {
	name     string
	kind     Kind
	advanced bool
	meta     map[string]string
}

func (s basicSchema) Name() string {
	return s.name
}

func (s basicSchema) Kind() Kind {
	return s.kind
}

func (s basicSchema) Fields() []Field {
	return nil
}

func (s basicSchema) Advanced() bool {
	return s.advanced
}

func (s basicSchema) Meta() map[string]string {
	return s.meta
}

type structSchema struct {
	name     string
	fields   []Field
	advanced bool
}

func (s structSchema) Name() string {
	return s.name
}

func (s structSchema) Kind() Kind {
	return KindStruct
}

func (s structSchema) Fields() []Field {
	return s.fields
}

func (s structSchema) Advanced() bool {
	return s.advanced
}

func (s structSchema) Meta() map[string]string {
	return map[string]string{}
}

func NewCueSchema(name string, v cue.Value) (Schema, error) {
	nameAttr := v.Attribute("name")
	if nameAttr.Err() == nil {
		name = nameAttr.Contents()
	}
	role := ""
	roleAttr := v.Attribute("role")
	if roleAttr.Err() == nil {
		role = strings.ToLower(roleAttr.Contents())
	}
	switch v.IncompleteKind() {
	case cue.StringKind:
		if role == "vpnauthkey" {
			meta := map[string]string{}
			usernameAttr := v.Attribute("usernameField")
			meta["usernameField"] = strings.ToLower(usernameAttr.Contents())
			return basicSchema{name, KindVPNAuthKey, true, meta}, nil
		} else {
			return basicSchema{name, KindString, false, nil}, nil
		}
	case cue.BoolKind:
		return basicSchema{name, KindBoolean, false, nil}, nil
	case cue.NumberKind:
		return basicSchema{name, KindNumber, false, nil}, nil
	case cue.IntKind:
		if role == "port" {
			return basicSchema{name, KindPort, true, nil}, nil
		} else {
			return basicSchema{name, KindInt, false, nil}, nil
		}
	case cue.ListKind:
		if isMultiNetwork(v) {
			return basicSchema{name, KindMultiNetwork, false, nil}, nil
		}
		return basicSchema{name, KindArrayString, false, nil}, nil
	case cue.StructKind:
		if isNetwork(v) {
			return basicSchema{name, KindNetwork, false, nil}, nil
		} else if isAuth(v) {
			return basicSchema{name, KindAuth, false, nil}, nil
		} else if isSSHKey(v) {
			return basicSchema{name, KindSSHKey, true, nil}, nil
		}
		s := structSchema{name, make([]Field, 0), false}
		f, err := v.Fields(cue.Schema())
		if err != nil {
			return nil, err
		}
		for f.Next() {
			scm, err := NewCueSchema(f.Selector().String(), f.Value())
			if err != nil {
				return nil, err
			}
			s.fields = append(s.fields, Field{f.Selector().String(), scm})
		}
		return s, nil
	default:
		return nil, fmt.Errorf("SHOULD NOT REACH!")
	}
}
