package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"time"
)

type Event struct {
	Time       string `json:"time"`
	ObservedAt string `json:"observed_at"`
	Statement  string `json:"statement"`
	Evidence   string `json:"evidence"`
	Kind       string `json:"kind"`
}
type Action struct {
	ID           string `json:"id"`
	Owner        string `json:"owner"`
	Due          string `json:"due"`
	Change       string `json:"change"`
	Acceptance   string `json:"acceptance"`
	Status       string `json:"status"`
	Verification string `json:"verification"`
}
type Review struct {
	Synthetic bool     `json:"synthetic"`
	Incident  string   `json:"incident"`
	Events    []Event  `json:"events"`
	Actions   []Action `json:"actions"`
}

func validate(r Review) error {
	if r.Incident == "" || len(r.Events) == 0 {
		return errors.New("missing incident or timeline")
	}
	var prev time.Time
	for _, e := range r.Events {
		when, err := time.Parse(time.RFC3339, e.Time)
		if err != nil {
			return errors.New("invalid event time")
		}
		observed, err := time.Parse(time.RFC3339, e.ObservedAt)
		if err != nil || observed.Before(when) {
			return errors.New("invalid observation time")
		}
		if when.Before(prev) {
			return errors.New("timeline not sorted")
		}
		prev = when
		if e.Statement == "" || e.Evidence == "" {
			return errors.New("timeline lacks evidence")
		}
		if e.Kind != "fact" && e.Kind != "hypothesis" {
			return errors.New("unknown evidence kind")
		}
	}
	seen := map[string]bool{}
	for _, a := range r.Actions {
		if a.ID == "" || seen[a.ID] {
			return errors.New("invalid action id")
		}
		seen[a.ID] = true
		if a.Owner == "" {
			return errors.New("action missing owner")
		}
		if _, err := time.Parse("2006-01-02", a.Due); err != nil {
			return errors.New("action missing valid due date")
		}
		if a.Change == "" || a.Acceptance == "" {
			return errors.New("action missing change or acceptance")
		}
		if a.Status != "open" && a.Status != "done" {
			return errors.New("unknown action status")
		}
		if a.Status == "done" && a.Verification == "" {
			return errors.New("done action missing verification")
		}
	}
	return nil
}
func load(path string) (Review, error) {
	var r Review
	b, err := os.ReadFile(path)
	if err != nil {
		return r, err
	}
	err = json.Unmarshal(b, &r)
	return r, err
}
func main() {
	r, err := load("synthetic.json")
	if err != nil {
		panic(err)
	}
	if err = validate(r); err != nil {
		panic(err)
	}
	fmt.Printf("synthetic=%v events=%d actions=%d validation=ok\n", r.Synthetic, len(r.Events), len(r.Actions))
	bad := r
	bad.Actions = append([]Action(nil), r.Actions...)
	bad.Actions[0].Owner = ""
	fmt.Println("missing owner:", validate(bad))
	bad = r
	bad.Actions = append([]Action(nil), r.Actions...)
	bad.Actions[0].Status = "done"
	bad.Actions[0].Verification = ""
	fmt.Println("premature close:", validate(bad))
}
