package installer

import (
	"bytes"
	_ "embed"
	"encoding/json"
	"fmt"
	template "html/template"
	"net"
	"net/netip"
	"strings"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/cuecontext"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/load"
	cueyaml "cuelang.org/go/encoding/yaml"
	helmv2 "github.com/fluxcd/helm-controller/api/v2"
)

//go:embed app_configs/dodo_app.cue
var dodoAppCue []byte

//go:embed app_configs/app_base.cue
var cueBaseConfig []byte

//go:embed app_configs/app_global_env.cue
var cueEnvAppGlobal []byte

//go:embed app_configs/app_global_infra.cue
var cueInfraAppGlobal []byte

type Access struct {
	Type       string `json:"type"`
	Name       string `json:"name"`
	HTTPS      *AccessHTTPS
	SSH        *AccessSSH
	TCP        *AccessTCP
	UDP        *AccessUDP
	PostgreSQL *AccessPostgreSQL
	MongoDB    *AccessMongoDB
}

func (a Access) MarshalJSON() ([]byte, error) {
	var buf bytes.Buffer
	switch a.Type {
	case "https":
		if err := json.NewEncoder(&buf).Encode(struct {
			AccessHTTPS
			Type string `json:"type"`
			Name string `json:"name"`
		}{*a.HTTPS, a.Type, a.Name}); err != nil {
			return nil, err
		}
	case "ssh":
		if err := json.NewEncoder(&buf).Encode(struct {
			AccessSSH
			Type string `json:"type"`
			Name string `json:"name"`
		}{*a.SSH, a.Type, a.Name}); err != nil {
			return nil, err
		}
	case "tcp":
		if err := json.NewEncoder(&buf).Encode(struct {
			AccessTCP
			Type string `json:"type"`
			Name string `json:"name"`
		}{*a.TCP, a.Type, a.Name}); err != nil {
			return nil, err
		}
	case "udp":
		if err := json.NewEncoder(&buf).Encode(struct {
			AccessUDP
			Type string `json:"type"`
			Name string `json:"name"`
		}{*a.UDP, a.Type, a.Name}); err != nil {
			return nil, err
		}
	case "postgresql":
		if err := json.NewEncoder(&buf).Encode(struct {
			AccessPostgreSQL
			Type string `json:"type"`
			Name string `json:"name"`
		}{*a.PostgreSQL, a.Type, a.Name}); err != nil {
			return nil, err
		}
	case "mongodb":
		if err := json.NewEncoder(&buf).Encode(struct {
			AccessMongoDB
			Type string `json:"type"`
			Name string `json:"name"`
		}{*a.MongoDB, a.Type, a.Name}); err != nil {
			return nil, err
		}
	default:
		panic("MUST NOT REACH!")
	}
	return buf.Bytes(), nil
}

type AccessHTTPS struct {
	Address string `json:"address"`
}

type AccessSSH struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

type AccessTCP struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

type AccessUDP struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

type AccessPostgreSQL struct {
	Host     string `json:"host"`
	Port     int    `json:"port"`
	Database string `json:"database"`
	Username string `json:"username"`
	Password string `json:"password"`
}

type AccessMongoDB struct {
	Host     string `json:"host"`
	Port     int    `json:"port"`
	Database string `json:"database"`
	Username string `json:"username"`
	Password string `json:"password"`
}

type rendered struct {
	Name            string
	Readme          string
	Cluster         string
	Namespaces      []Namespace
	Resources       CueAppData
	HelmCharts      HelmCharts
	ContainerImages map[string]ContainerImage
	Ports           []PortForward
	ClusterProxies  map[string]ClusterProxy
	Data            CueAppData
	URL             string
	Help            []HelpDocument
	Icon            string
	Access          []Access
	Raw             []byte
}

type Namespace struct {
	Name       string `json:"name"`
	Kubeconfig string `json:"kubeconfig,omitempty"`
}

type HelpDocument struct {
	Title    string
	Contents string
	Children []HelpDocument
}

type ContainerImage struct {
	Registry   string `json:"registry"`
	Repository string `json:"repository"`
	Name       string `json:"name"`
	Tag        string `json:"tag"`
}

type helmChartRef struct {
	Kind string `json:"kind"`
}

type HelmCharts struct {
	Git map[string]HelmChartGitRepo
}

type HelmChartGitRepo struct {
	Address string `json:"address"`
	Branch  string `json:"branch"`
	Path    string `json:"path"`
}

type EnvAppRendered struct {
	rendered
	Config AppInstanceConfig
}

type InfraAppRendered struct {
	rendered
	Config InfraAppInstanceConfig
}

type ClusterProxy struct {
	From string `json:"from"`
	To   string `json:"to"`
}

type PortForward struct {
	Cluster  string  `json:"clusterName,omitempty"`
	Network  Network `json:"network"`
	Protocol string  `json:"protocol"`
	Port     int     `json:"port"`
	Service  struct {
		Name      string `json:"name"`
		Namespace string `json:"namespace,omitempty"`
		Port      int    `json:"port"`
	} `json:"service"`
}

type AppType int

const (
	AppTypeInfra AppType = iota
	AppTypeEnv
)

type App interface {
	Name() string
	Type() AppType
	Slug() string
	Description() string
	Icon() template.HTML
	Schema() Schema
	Namespace() string
}

type InfraConfig struct {
	Name                 string   `json:"pcloudEnvName,omitempty"` // #TODO(gio): change to name
	PublicIP             []net.IP `json:"publicIP,omitempty"`
	InfraNamespacePrefix string   `json:"namespacePrefix,omitempty"`
	InfraAdminPublicKey  []byte   `json:"infraAdminPublicKey,omitempty"`
}

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

type InfraApp interface {
	App
	Render(release Release, infra InfraConfig, networks []InfraNetwork, values map[string]any, charts map[string]helmv2.HelmChartTemplateSpec) (InfraAppRendered, error)
}

type EnvNetwork struct {
	DNS            net.IP `json:"dns,omitempty"`
	DNSInClusterIP net.IP `json:"dnsInClusterIP,omitempty"`
	Ingress        net.IP `json:"ingress,omitempty"`
	Headscale      net.IP `json:"headscale,omitempty"`
	ServicesFrom   net.IP `json:"servicesFrom,omitempty"`
	ServicesTo     net.IP `json:"servicesTo,omitempty"`
}

func NewEnvNetwork(subnet net.IP) (EnvNetwork, error) {
	addr, err := netip.ParseAddr(subnet.String())
	if err != nil {
		return EnvNetwork{}, err
	}
	if !addr.Is4() {
		return EnvNetwork{}, fmt.Errorf("Expected IPv4, got %s instead", addr)
	}
	dns := addr.Next()
	ingress := dns.Next()
	headscale := ingress.Next()
	b := addr.AsSlice()
	if b[3] != 0 {
		return EnvNetwork{}, fmt.Errorf("Expected last byte to be zero, got %d instead", b[3])
	}
	b[3] = 10
	servicesFrom, ok := netip.AddrFromSlice(b)
	if !ok {
		return EnvNetwork{}, fmt.Errorf("Must not reach")
	}
	b[3] = 254
	servicesTo, ok := netip.AddrFromSlice(b)
	if !ok {
		return EnvNetwork{}, fmt.Errorf("Must not reach")
	}
	b[3] = b[2]
	b[2] = b[1]
	b[0] = 10
	b[1] = 44
	dnsInClusterIP, ok := netip.AddrFromSlice(b)
	if !ok {
		return EnvNetwork{}, fmt.Errorf("Must not reach")
	}
	return EnvNetwork{
		DNS:            net.ParseIP(dns.String()),
		DNSInClusterIP: net.ParseIP(dnsInClusterIP.String()),
		Ingress:        net.ParseIP(ingress.String()),
		Headscale:      net.ParseIP(headscale.String()),
		ServicesFrom:   net.ParseIP(servicesFrom.String()),
		ServicesTo:     net.ParseIP(servicesTo.String()),
	}, nil
}

type EnvConfig struct {
	Id              string     `json:"id,omitempty"`
	InfraName       string     `json:"pcloudEnvName,omitempty"`
	Domain          string     `json:"domain,omitempty"`
	PrivateDomain   string     `json:"privateDomain,omitempty"`
	ContactEmail    string     `json:"contactEmail,omitempty"`
	AdminPublicKey  string     `json:"adminPublicKey,omitempty"`
	PublicIP        []net.IP   `json:"publicIP,omitempty"`
	NameserverIP    []net.IP   `json:"nameserverIP,omitempty"`
	NamespacePrefix string     `json:"namespacePrefix,omitempty"`
	Network         EnvNetwork `json:"network,omitempty"`
}

type EnvApp interface {
	App
	Render(
		release Release,
		env EnvConfig,
		networks []Network,
		clusters []Cluster,
		values map[string]any,
		charts map[string]helmv2.HelmChartTemplateSpec,
		vpnKeyGen VPNAPIClient,
	) (EnvAppRendered, error)
}

type cueApp struct {
	name        string
	description string
	icon        template.HTML
	namespace   string
	schema      Schema
	cfg         cue.Value
	data        CueAppData
}

type CueAppData map[string][]byte

func ParseCueAppConfig(data CueAppData) (cue.Value, error) {
	ctx := cuecontext.New()
	buildCtx := build.NewContext()
	cfg := &load.Config{
		Context: buildCtx,
		Overlay: map[string]load.Source{},
	}
	names := make([]string, 0)
	for n, b := range data {
		a := fmt.Sprintf("/%s", n)
		names = append(names, a)
		cfg.Overlay[a] = load.FromString("package main\n\n" + string(b))
	}
	instances := load.Instances(names, cfg)
	for _, inst := range instances {
		if inst.Err != nil {
			return cue.Value{}, inst.Err
		}
	}
	if len(instances) != 1 {
		return cue.Value{}, fmt.Errorf("invalid")
	}
	ret := ctx.BuildInstance(instances[0])
	if err := ret.Err(); err != nil {
		return cue.Value{}, err
	}
	if err := ret.Validate(); err != nil {
		return cue.Value{}, err
	}
	return ret, nil
}

func newCueApp(config cue.Value, data CueAppData) (cueApp, error) {
	cfg := struct {
		Name        string `json:"name"`
		Namespace   string `json:"namespace"`
		Description string `json:"description"`
		Icon        string `json:"icon"`
	}{}
	if err := config.Decode(&cfg); err != nil {
		return cueApp{}, err
	}
	schema, err := NewCueSchema("input", config.LookupPath(cue.ParsePath("input")))
	if err != nil {
		return cueApp{}, err
	}
	return cueApp{
		name:        cfg.Name,
		description: cfg.Description,
		icon:        template.HTML(cfg.Icon),
		namespace:   cfg.Namespace,
		schema:      schema,
		cfg:         config,
		data:        data,
	}, nil
}

func ParseAndCreateNewCueApp(data CueAppData) (cueApp, error) {
	config, err := ParseCueAppConfig(data)
	if err != nil {
		return cueApp{}, fmt.Errorf(errors.Details(err, nil))
	}
	return newCueApp(config, data)
}

func (a cueApp) Name() string {
	return a.name
}

func (a cueApp) Slug() string {
	return strings.ReplaceAll(strings.ToLower(a.name), " ", "-")
}

func (a cueApp) Description() string {
	return a.description
}

func (a cueApp) Icon() template.HTML {
	return a.icon
}

func (a cueApp) Schema() Schema {
	return a.schema
}

func (a cueApp) Namespace() string {
	return a.namespace
}

func (a cueApp) render(values map[string]any) (rendered, error) {
	ret := rendered{
		Name:      a.Slug(),
		Resources: make(CueAppData),
		HelmCharts: HelmCharts{
			Git: make(map[string]HelmChartGitRepo),
		},
		ContainerImages: make(map[string]ContainerImage),
		Ports:           make([]PortForward, 0),
		Data:            a.data,
	}
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(values); err != nil {
		return rendered{}, err
	}
	ctx := a.cfg.Context()
	d := ctx.CompileBytes(buf.Bytes())
	res := a.cfg.Unify(d).Eval()
	if err := res.Err(); err != nil {
		return rendered{}, fmt.Errorf(errors.Details(err, nil))
	}
	if err := res.Validate(); err != nil {
		return rendered{}, err
	}
	full, err := json.MarshalIndent(res, "", "\t")
	if err != nil {
		return rendered{}, err
	}
	ret.Raw = full
	ret.Data["rendered.json"] = full
	readme, err := res.LookupPath(cue.ParsePath("readme")).String()
	if err != nil {
		return rendered{}, err
	}
	ret.Readme = readme
	res.LookupPath(cue.ParsePath("input.cluster.name")).Decode(&ret.Cluster)
	if err := res.LookupPath(cue.ParsePath("output.clusterProxy")).Decode(&ret.ClusterProxies); err != nil {
		return rendered{}, err
	}
	if err := res.LookupPath(cue.ParsePath("namespaces")).Decode(&ret.Namespaces); err != nil {
		return rendered{}, err
	}
	if err := res.LookupPath(cue.ParsePath("output.openPort")).Decode(&ret.Ports); err != nil {
		return rendered{}, err
	}
	{
		charts := res.LookupPath(cue.ParsePath("output.charts"))
		i, err := charts.Fields()
		if err != nil {
			return rendered{}, err
		}
		for i.Next() {
			var chartRef helmChartRef
			if err := i.Value().Decode(&chartRef); err != nil {
				return rendered{}, err
			}
			if chartRef.Kind == "GitRepository" {
				var chart HelmChartGitRepo
				if err := i.Value().Decode(&chart); err != nil {
					return rendered{}, err
				}
				ret.HelmCharts.Git[cleanName(i.Selector().String())] = chart
			}
		}
	}
	{
		images := res.LookupPath(cue.ParsePath("output.images"))
		i, err := images.Fields()
		if err != nil {
			return rendered{}, err
		}
		for i.Next() {
			var img ContainerImage
			if err := i.Value().Decode(&img); err != nil {
				return rendered{}, err
			}
			ret.ContainerImages[cleanName(i.Selector().String())] = img
		}
	}
	{
		helm := res.LookupPath(cue.ParsePath("output.helm"))
		i, err := helm.Fields()
		if err != nil {
			return rendered{}, err
		}
		for i.Next() {
			if contents, err := cueyaml.Encode(i.Value()); err != nil {
				return rendered{}, err
			} else {
				name := fmt.Sprintf("%s.yaml", cleanName(i.Selector().String()))
				ret.Resources[name] = contents
			}
		}
	}
	{
		resources := res.LookupPath(cue.ParsePath("resources"))
		i, err := resources.Fields()
		if err != nil {
			return rendered{}, err
		}
		for i.Next() {
			if contents, err := cueyaml.Encode(i.Value()); err != nil {
				return rendered{}, err
			} else {
				name := fmt.Sprintf("%s.yaml", cleanName(i.Selector().String()))
				ret.Resources[name] = contents
			}
		}
	}
	helpValue := res.LookupPath(cue.ParsePath("help"))
	if helpValue.Exists() {
		if err := helpValue.Decode(&ret.Help); err != nil {
			return rendered{}, err
		}
	}
	url, err := res.LookupPath(cue.ParsePath("url")).String()
	if err != nil {
		return rendered{}, err
	}
	ret.URL = url
	icon, err := res.LookupPath(cue.ParsePath("icon")).String()
	if err != nil {
		return rendered{}, err
	}
	ret.Icon = icon
	access, err := extractAccess(res.LookupPath(cue.ParsePath("outs")))
	if err != nil {
		return rendered{}, err
	}
	ret.Access = access
	return ret, nil
}

func extractAccessInternal(v cue.Value) ([]Access, error) {
	ret := []Access{}
	a := v.LookupPath(cue.ParsePath("access"))
	if err := a.Err(); err != nil {
		return nil, err
	}
	i, err := a.List()
	if err != nil {
		return nil, err
	}
	for i.Next() {
		n := i.Value().LookupPath(cue.ParsePath("name"))
		if err := n.Err(); err != nil {
			return nil, err
		}
		nn, err := n.String()
		if err != nil {
			return nil, err
		}
		t := i.Value().LookupPath(cue.ParsePath("type"))
		if err := t.Err(); err != nil {
			return nil, err
		}
		d, err := t.String()
		if err != nil {
			return nil, err
		}
		switch d {
		case "https":
			{
				var q AccessHTTPS
				if err := i.Value().Decode(&q); err != nil {
					return nil, err
				}
				ret = append(ret, Access{Type: "https", Name: nn, HTTPS: &q})
			}
		case "ssh":
			{
				var q AccessSSH
				if err := i.Value().Decode(&q); err != nil {
					return nil, err
				}
				ret = append(ret, Access{Type: "ssh", Name: nn, SSH: &q})
			}
		case "tcp":
			{
				var q AccessTCP
				if err := i.Value().Decode(&q); err != nil {
					return nil, err
				}
				ret = append(ret, Access{Type: "tcp", Name: nn, TCP: &q})
			}
		case "udp":
			{
				var q AccessUDP
				if err := i.Value().Decode(&q); err != nil {
					return nil, err
				}
				ret = append(ret, Access{Type: "udp", Name: nn, UDP: &q})
			}
		case "postgresql":
			{
				var q AccessPostgreSQL
				if err := i.Value().Decode(&q); err != nil {
					return nil, err
				}
				ret = append(ret, Access{Type: "postgresql", Name: nn, PostgreSQL: &q})
			}
		case "mongodb":
			{
				var q AccessMongoDB
				if err := i.Value().Decode(&q); err != nil {
					return nil, err
				}
				ret = append(ret, Access{Type: "mongodb", Name: nn, MongoDB: &q})
			}
		}
	}
	for _, sub := range []string{"ingress", "postgresql", "mongodb", "services", "vm"} {
		subout := v.LookupPath(cue.ParsePath(sub))
		if subout.Err() != nil {
			continue
		}
		if a, err := extractAccess(subout); err != nil {
			return nil, err
		} else {
			ret = append(ret, a...)
		}
	}
	return ret, nil
}

func extractAccess(v cue.Value) ([]Access, error) {
	if err := v.Err(); err != nil {
		return nil, err
	}
	i, err := v.Fields()
	if err != nil {
		return nil, err
	}
	ret := []Access{}
	for i.Next() {
		if a, err := extractAccessInternal(i.Value()); err != nil {
			return nil, fmt.Errorf(errors.Details(err, nil))
		} else {
			ret = append(ret, a...)
		}
	}
	return ret, nil
}

type cueEnvApp struct {
	cueApp
}

func NewCueEnvApp(data CueAppData) (EnvApp, error) {
	app, err := ParseAndCreateNewCueApp(data)
	if err != nil {
		return nil, err
	}
	return cueEnvApp{app}, nil
}

func NewDodoApp(appCfg []byte) (EnvApp, error) {
	return NewCueEnvApp(CueAppData{
		"app.cue":  appCfg,
		"base.cue": []byte(cueBaseConfig),
		"dodo.cue": dodoAppCue,
		"env.cue":  []byte(cueEnvAppGlobal),
	})
}

func (a cueEnvApp) Type() AppType {
	return AppTypeEnv
}

func merge(d map[string]any, v map[string]any) map[string]any {
	ret := map[string]any{}
	for k, val := range d {
		if vv, ok := v[k]; ok && vv != nil {
			if mv, ok := val.(map[string]any); ok {
				// TODO(gio): check that it is actually map
				ret[k] = merge(mv, vv.(map[string]any))
			} else {
				ret[k] = vv
			}
		} else {
			ret[k] = val
		}
	}
	for k, v := range v {
		if v != nil {
			if _, ok := d[k]; !ok {
				ret[k] = v
			}
		}
	}
	return ret
}

func (a cueEnvApp) Render(
	release Release,
	env EnvConfig,
	networks []Network,
	clusters []Cluster,
	values map[string]any,
	charts map[string]helmv2.HelmChartTemplateSpec,
	vpnKeyGen VPNAPIClient,
) (EnvAppRendered, error) {
	dv, err := ExtractDefaultValues(a.cueApp.cfg.LookupPath(cue.ParsePath("input")))
	if err != nil {
		return EnvAppRendered{}, err
	}
	mv := merge(dv.(map[string]any), values)
	derived, err := deriveValues(mv, values, a.Schema(), networks, clusters, vpnKeyGen)
	if err != nil {
		return EnvAppRendered{}, err
	}
	if charts == nil {
		charts = make(map[string]helmv2.HelmChartTemplateSpec)
	}
	if clusters == nil {
		clusters = []Cluster{}
	}
	ret, err := a.cueApp.render(map[string]any{
		"global":      env,
		"release":     release,
		"input":       derived,
		"localCharts": charts,
		"networks":    NetworkMap(networks),
		"clusters":    clusters,
	})
	if err != nil {
		return EnvAppRendered{}, err
	}
	return EnvAppRendered{
		rendered: ret,
		Config: AppInstanceConfig{
			AppId:   a.Slug(),
			Env:     env,
			Release: release,
			Values:  values,
			Input:   derived,
			URL:     ret.URL,
			Help:    ret.Help,
			Icon:    ret.Icon,
		},
	}, nil
}

type cueInfraApp struct {
	cueApp
}

func NewCueInfraApp(data CueAppData) (InfraApp, error) {
	app, err := ParseAndCreateNewCueApp(data)
	if err != nil {
		return nil, err
	}
	return cueInfraApp{app}, nil
}

func (a cueInfraApp) Type() AppType {
	return AppTypeInfra
}

func (a cueInfraApp) Render(release Release, infra InfraConfig, networks []InfraNetwork, values map[string]any, charts map[string]helmv2.HelmChartTemplateSpec) (InfraAppRendered, error) {
	if charts == nil {
		charts = make(map[string]helmv2.HelmChartTemplateSpec)
	}
	ret, err := a.cueApp.render(map[string]any{
		"global":      infra,
		"release":     release,
		"input":       values,
		"localCharts": charts,
		"networks":    InfraNetworkMap(networks),
	})
	if err != nil {
		return InfraAppRendered{}, err
	}
	return InfraAppRendered{
		rendered: ret,
		Config: InfraAppInstanceConfig{
			AppId:   a.Slug(),
			Infra:   infra,
			Release: release,
			Values:  values,
			Input:   values,
			URL:     ret.URL,
			Help:    ret.Help,
		},
	}, nil
}

func cleanName(s string) string {
	return strings.ReplaceAll(strings.ReplaceAll(s, "\"", ""), "'", "")
}

func join[T fmt.Stringer](items []T, sep string) string {
	var tmp []string
	for _, i := range items {
		tmp = append(tmp, i.String())
	}
	return strings.Join(tmp, ",")
}

func NetworkMap(networks []Network) map[string]Network {
	ret := make(map[string]Network)
	for _, n := range networks {
		ret[strings.ToLower(n.Name)] = n
	}
	return ret
}

func InfraNetworkMap(networks []InfraNetwork) map[string]InfraNetwork {
	ret := make(map[string]InfraNetwork)
	for _, n := range networks {
		ret[strings.ToLower(n.Name)] = n
	}
	return ret
}
