package store

// v0.51.0 dr_tier one-time legacy backfill — "initialize from reality": on the migration that
// ADDS the column, a customer whose host already carries an ENABLED pbs_dr descriptor flips ON;
// everyone else stays OFF (never auto-cascade a legacy box). Simulated against a genuine
// pre-v0.51.0 database file (tables without dr_tier), then opened through store.New so the REAL
// migrate() path runs. Red-proof partner: make the backfill ignore `"enabled":false` vs true
// (set every pbs_dr customer ON) → the disabled-descriptor case fails.

import (
	"database/sql"
	"io"
	"log"
	"path/filepath"
	"testing"

	_ "modernc.org/sqlite"
)

func TestDRTierBackfill_InitializesFromReality(t *testing.T) {
	dbPath := filepath.Join(t.TempDir(), "legacy.db")

	// 1. Build a PRE-v0.51.0 database: customer_configs + hosts WITHOUT dr_tier.
	raw, err := sql.Open("sqlite", dbPath)
	if err != nil {
		t.Fatal(err)
	}
	mustExec := func(q string, args ...any) {
		t.Helper()
		if _, err := raw.Exec(q, args...); err != nil {
			t.Fatalf("legacy seed: %v (%s)", err, q)
		}
	}
	mustExec(`CREATE TABLE customer_configs (
		customer_id TEXT PRIMARY KEY,
		customer_name TEXT NOT NULL DEFAULT '',
		domain TEXT NOT NULL DEFAULT '',
		email TEXT NOT NULL DEFAULT '',
		retrieval_password TEXT NOT NULL,
		api_key TEXT NOT NULL,
		config_json TEXT NOT NULL DEFAULT '{}',
		created_at DATETIME NOT NULL DEFAULT (datetime('now')),
		updated_at DATETIME NOT NULL DEFAULT (datetime('now'))
	)`)
	mustExec(`CREATE TABLE hosts (
		host_id TEXT PRIMARY KEY,
		customer_id TEXT NOT NULL,
		api_key TEXT NOT NULL,
		agent_version TEXT NOT NULL DEFAULT '',
		last_report_at DATETIME,
		desired_json TEXT NOT NULL DEFAULT '{}',
		desired_generation INTEGER NOT NULL DEFAULT 0,
		dr_record_json TEXT NOT NULL DEFAULT '{}',
		created_at DATETIME NOT NULL DEFAULT (datetime('now')),
		updated_at DATETIME NOT NULL DEFAULT (datetime('now'))
	)`)
	seedCustomer := func(id string) {
		mustExec(`INSERT INTO customer_configs (customer_id, retrieval_password, api_key) VALUES (?, ?, ?)`,
			id, "pw", "key-"+id)
	}
	seedCustomer("applied")   // host carries an ENABLED descriptor → must flip ON
	seedCustomer("disabled")  // descriptor present but enabled:false → must stay OFF
	seedCustomer("plain")     // no descriptor at all → must stay OFF
	seedCustomer("hostless")  // no host row → must stay OFF
	mustExec(`INSERT INTO hosts (host_id, customer_id, api_key, desired_json) VALUES (?, ?, ?, ?)`,
		"applied-01", "applied", "h1",
		`{"pbs_dr":{"enabled":true,"storage_id":"felhom-pbs","namespace":"applied"}}`)
	mustExec(`INSERT INTO hosts (host_id, customer_id, api_key, desired_json) VALUES (?, ?, ?, ?)`,
		"disabled-01", "disabled", "h2",
		`{"pbs_dr":{"enabled":false,"storage_id":"felhom-pbs","namespace":"disabled"}}`)
	mustExec(`INSERT INTO hosts (host_id, customer_id, api_key, desired_json) VALUES (?, ?, ?, ?)`,
		"plain-01", "plain", "h3", `{}`)
	if err := raw.Close(); err != nil {
		t.Fatal(err)
	}

	// 2. Open through the real store — migrate() adds dr_tier and runs the one-time backfill.
	st, err := New(dbPath, log.New(io.Discard, "", 0))
	if err != nil {
		t.Fatalf("store.New over the legacy db: %v", err)
	}
	defer st.Close()

	want := map[string]bool{"applied": true, "disabled": false, "plain": false, "hostless": false}
	for id, wantOn := range want {
		cfg, err := st.GetCustomerConfig(id)
		if err != nil || cfg == nil {
			t.Fatalf("read %s: %v", id, err)
		}
		if cfg.DRTier != wantOn {
			t.Errorf("customer %s: dr_tier=%v, want %v (initialize from reality)", id, cfg.DRTier, wantOn)
		}
	}

	// 3. The backfill is ONE-TIME: a later flag change must survive a re-open (the ALTER now
	// fails → no re-backfill stomping operator decisions).
	cfg, _ := st.GetCustomerConfig("applied")
	cfg.DRTier = false // operator opts the customer out
	if err := st.SaveCustomerConfig(cfg); err != nil {
		t.Fatal(err)
	}
	st.Close()
	st2, err := New(dbPath, log.New(io.Discard, "", 0))
	if err != nil {
		t.Fatal(err)
	}
	defer st2.Close()
	cfg2, _ := st2.GetCustomerConfig("applied")
	if cfg2.DRTier {
		t.Fatal("re-open re-ran the backfill and stomped the operator's opt-out")
	}
}
