package main

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

type check struct {
	Name   string `json:"name"`
	Pass   bool   `json:"pass"`
	Detail string `json:"detail"`
}

type certReport struct {
	GeneratedAt string  `json:"generated_at"`
	Node        string  `json:"node"`
	PVEVersion  string  `json:"pve_version"`
	Checks      []check `json:"checks"`
	AllPass     bool    `json:"all_pass"`
	RequestID   string  `json:"request_id"` // sha256 over node+checks; quote it to your Netquor Engineer
}

type certOpts struct{ WANBridge, LANBridge string }

// buildReport runs the read-only host checks a Netquor Engineer reviews.
func buildReport(c *pveClient, o certOpts) (*certReport, error) {
	r := &certReport{GeneratedAt: time.Now().UTC().Format(time.RFC3339), Node: c.node}
	add := func(n string, ok bool, d string) { r.Checks = append(r.Checks, check{n, ok, d}) }

	var ver struct {
		Version string `json:"version"`
	}
	if err := c.get("/version", &ver); err != nil {
		return nil, fmt.Errorf("proxmox unreachable: %w", err)
	}
	r.PVEVersion = ver.Version
	add("proxmox_reachable", true, "Proxmox VE "+ver.Version)
	add("proxmox_version", !strings.HasPrefix(ver.Version, "6.") && !strings.HasPrefix(ver.Version, "7."), "PVE 8+ required")

	nets, err := c.networks()
	if err != nil {
		return nil, err
	}
	by := map[string]netIface{}
	for _, n := range nets {
		by[n.Iface] = n
	}
	_, hasWAN := by[o.WANBridge]
	add("wan_bridge", hasWAN, o.WANBridge+" exists")
	lan, hasLAN := by[o.LANBridge]
	add("tenant_bridge", hasLAN, o.LANBridge+" exists")
	add("tenant_bridge_isolated", hasLAN && lan.vlanAware(), o.LANBridge+" is VLAN-aware (tenant isolation)")

	vms, err := c.vms()
	if err != nil {
		return nil, err
	}
	var vy *vmInfo
	for i := range vms {
		if strings.HasPrefix(strings.ToLower(vms[i].Name), "vyos") {
			vy = &vms[i]
			break
		}
	}
	add("vyos_present", vy != nil, "a VM named vyos* exists")
	add("vyos_running", vy != nil && vy.Status == "running", "VyOS router is running")

	r.AllPass = true
	for _, k := range r.Checks {
		r.AllPass = r.AllPass && k.Pass
	}
	h := sha256.New()
	b, _ := json.Marshal(struct {
		N string
		C []check
	}{r.Node, r.Checks})
	h.Write(b)
	r.RequestID = hex.EncodeToString(h.Sum(nil))[:16]
	return r, nil
}
