package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/tidbcloud/AgentTeam/internal/workflow/plan"
	"gopkg.in/yaml.v3"
)

type block struct {
	Path   string `json:"path"`
	Source string `json:"source"`
}

type finding struct {
	Path    string `json:"path"`
	Code    string `json:"code"`
	Message string `json:"message"`
}

func main() {
	var blocks []block
	if err := json.NewDecoder(os.Stdin).Decode(&blocks); err != nil {
		fail(fmt.Sprintf("decode checker input: %v", err))
	}
	findings := make([]finding, 0)
	for _, candidate := range blocks {
		var document yaml.Node
		if err := yaml.Unmarshal([]byte(candidate.Source), &document); err != nil {
			findings = append(findings, finding{
				Path: candidate.Path, Code: "yaml.invalid", Message: err.Error(),
			})
			continue
		}
		if !isPlanDocument(document) {
			continue
		}
		_, diagnostics, err := plan.Compile([]byte(candidate.Source))
		if err != nil {
			findings = append(findings, finding{
				Path: candidate.Path, Code: "plan.compile_failed", Message: err.Error(),
			})
			continue
		}
		for _, diagnostic := range diagnostics {
			findings = append(findings, finding{
				Path: candidate.Path, Code: diagnostic.Code, Message: diagnostic.Message,
			})
		}
	}
	if err := json.NewEncoder(os.Stdout).Encode(findings); err != nil {
		fail(fmt.Sprintf("encode checker output: %v", err))
	}
}

func isPlanDocument(document yaml.Node) bool {
	node := &document
	if node.Kind == yaml.DocumentNode && len(node.Content) == 1 {
		node = node.Content[0]
	}
	if node.Kind != yaml.MappingNode {
		return false
	}
	for index := 0; index+1 < len(node.Content); index += 2 {
		key, value := node.Content[index], node.Content[index+1]
		if key.Value == "apiVersion" && value.Value == "loop.plan/v1" {
			return true
		}
	}
	return false
}

func fail(message string) {
	fmt.Fprintln(os.Stderr, message)
	os.Exit(1)
}
