// Command legacy-report-to-json converts a legacy text-format Galaxy
// turn report (the "dg" / "gplus" engines) into a JSON envelope
// readable by the UI client's DEV-only synthetic-report loader:
//
//	{
//	  "version": 1,
//	  "report":  <Report JSON>,
//	  "battles": { "<uuid>": <BattleReport JSON>, ... }
//	}
//
// Carrying the per-turn report and the full BattleReports in one
// payload lets the synthetic loader register the battles up-front
// so the Battle Viewer can render any battle without a network
// fetch. The bare Report shape (no envelope) the lobby loader
// historically accepted remains backward-compatible on the UI side.
package main

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

	legacyreport "galaxy/legacy-report"
	"galaxy/model/report"
)

// envelope is the on-disk shape emitted by this CLI. `Version` lets
// the UI loader distinguish a v1 envelope from a bare Report; future
// versions can bump it without breaking older synthetic JSON files.
type envelope struct {
	Version int                            `json:"version"`
	Report  report.Report                  `json:"report"`
	Battles map[string]report.BattleReport `json:"battles,omitempty"`
}

func main() {
	in := flag.String("in", "", "path to legacy .REP file (use - for stdin)")
	out := flag.String("out", "", "path to write JSON to (use - or empty for stdout)")
	flag.Parse()

	if *in == "" {
		fmt.Fprintln(os.Stderr, "usage: legacy-report-to-json --in <path|-> [--out <path|->]")
		os.Exit(2)
	}

	r, closeIn, err := openInput(*in)
	if err != nil {
		fmt.Fprintf(os.Stderr, "open input: %v\n", err)
		os.Exit(1)
	}
	defer closeIn()

	rep, battles, err := legacyreport.Parse(r)
	if err != nil {
		fmt.Fprintf(os.Stderr, "parse: %v\n", err)
		os.Exit(1)
	}

	w, closeOut, err := openOutput(*out)
	if err != nil {
		fmt.Fprintf(os.Stderr, "open output: %v\n", err)
		os.Exit(1)
	}
	defer closeOut()

	env := envelope{Version: 1, Report: rep}
	if len(battles) > 0 {
		env.Battles = make(map[string]report.BattleReport, len(battles))
		for i := range battles {
			env.Battles[battles[i].ID.String()] = battles[i]
		}
	}

	enc := json.NewEncoder(w)
	enc.SetIndent("", "  ")
	if err := enc.Encode(env); err != nil {
		fmt.Fprintf(os.Stderr, "encode: %v\n", err)
		os.Exit(1)
	}
}

func openInput(path string) (io.Reader, func(), error) {
	if path == "-" {
		return os.Stdin, func() {}, nil
	}
	f, err := os.Open(path)
	if err != nil {
		return nil, nil, err
	}
	return f, func() { _ = f.Close() }, nil
}

func openOutput(path string) (io.Writer, func(), error) {
	if path == "" || path == "-" {
		return os.Stdout, func() {}, nil
	}
	f, err := os.Create(path)
	if err != nil {
		return nil, nil, err
	}
	return f, func() { _ = f.Close() }, nil
}
