package main

import (
	"log"
	"net/netip"

	"github.com/emicklei/go-restful"

	"novit.tech/direktil/pkg/localconfig"
)

var hostsFromTemplate = KVSecrets[HostFromTemplate]{"hosts-from-template"}

type HostFromTemplate struct {
	Template string
	IP       string
}

func (hft HostFromTemplate) ClusterName(cfg *localconfig.Config) string {
	for _, ht := range cfg.HostTemplates {
		if ht.Name == hft.Template {
			return ht.ClusterName
		}
	}
	return ""
}

func hostOrTemplate(cfg *localconfig.Config, name string) (host *localconfig.Host) {
	host = cfg.Host(name)
	if host != nil {
		return
	}

	hft, found, err := hostsFromTemplate.Get(name)
	if err != nil {
		log.Print("failed to read store: ", err)
		return
	}

	if !found {
		log.Print("no host named ", name)
		return
	}

	ht := cfg.HostTemplate(hft.Template)
	if ht == nil {
		log.Print("host ", name, " found but no template named ", hft.Template)
		return
	}

	host = &localconfig.Host{}
	*host = *ht
	host.Name = name
	host.IPs = []string{hft.IP}
	return
}

func wsHostsFromTemplateList(req *restful.Request, resp *restful.Response) {
	hostsFromTemplate.WsList(resp, "")
}

func wsHostsFromTemplateSet(req *restful.Request, resp *restful.Response) {
	name := req.PathParameter("name")

	cfg, err := readConfig()
	if err != nil {
		wsError(resp, err)
		return
	}

	v := HostFromTemplate{}
	if err := req.ReadEntity(&v); err != nil {
		wsBadRequest(resp, err.Error())
		return
	}

	if v.Template == "" {
		wsBadRequest(resp, "template is required")
		return
	}
	if v.IP == "" {
		wsBadRequest(resp, "ip is required")
		return
	}
	if _, err := netip.ParseAddr(v.IP); err != nil {
		wsBadRequest(resp, "bad IP: "+err.Error())
		return
	}

	found := false
	for _, ht := range cfg.HostTemplates {
		if ht.Name != v.Template {
			continue
		}
		found = true
		break
	}

	if !found {
		wsBadRequest(resp, "no host template with this name")
		return
	}

	if err := hostsFromTemplate.Put(name, v); err != nil {
		wsError(resp, err)
		return
	}

	updateState()
}

func wsHostsFromTemplateDelete(req *restful.Request, resp *restful.Response) {
	name := req.PathParameter("name")
	hostsFromTemplate.WsDel(req, resp, name)
	updateState()
}
