package lifecycle

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
)

// MetadbSeedReport is the persisted v1alpha2 metadb contract consumed by
// context materialization and later Tilt handoff slices.
type MetadbSeedReport struct {
	AdminDSN    string            `json:"admin_dsn"`
	ServiceDSNs map[string]string `json:"service_dsns"`
	SecretRef   string            `json:"secret_ref,omitempty"`
}

func LoadMetadbSeedReport(path string) (*MetadbSeedReport, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("read metadb seed report: %w", err)
	}
	var report MetadbSeedReport
	if err := json.Unmarshal(data, &report); err != nil {
		return nil, fmt.Errorf("parse metadb seed report: %w", err)
	}
	return &report, nil
}

func writeMetadbSeedReport(path string, report *MetadbSeedReport) error {
	if report == nil {
		return fmt.Errorf("metadb seed report is required")
	}
	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
		return fmt.Errorf("create metadb report dir: %w", err)
	}
	data, err := json.MarshalIndent(report, "", "  ")
	if err != nil {
		return fmt.Errorf("marshal metadb seed report: %w", err)
	}
	tmp, err := os.CreateTemp(filepath.Dir(path), "seed-report.json.*.tmp")
	if err != nil {
		return fmt.Errorf("create metadb report temp file: %w", err)
	}
	tmpPath := tmp.Name()
	defer os.Remove(tmpPath)
	if _, err := tmp.Write(data); err != nil {
		_ = tmp.Close()
		return fmt.Errorf("write metadb report temp file: %w", err)
	}
	if err := tmp.Close(); err != nil {
		return fmt.Errorf("close metadb report temp file: %w", err)
	}
	if err := os.Rename(tmpPath, path); err != nil {
		return fmt.Errorf("rename metadb report: %w", err)
	}
	return nil
}
