package control

import (
	"context"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"
)

func TestFinanceAPIHistoryAndReplay(t *testing.T) {
	server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "GET" || r.URL.RequestURI() != "/quality/summary?limit=100" || r.Header.Get("Authorization") != "" {
			t.Errorf("unexpected request %s %s", r.Method, r.URL.RequestURI())
		}
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`{"service":"data-platform-finance","recent_table_audits":[
{"run_id":"failed-1","target_table":"salesforce_account","status":"blocked","started_at":"2026-09-04 16:00:14","finished_at":"2026-09-04 16:00:33","error_message":"private row data"},
{"run_id":"good-1","target_table":"salesforce_org","status":"success","started_at":"2026-09-03T16:00:00Z","finished_at":"2026-09-03T16:00:01Z"},
{"run_id":"skip","target_table":"monthly_cloud_revrec","status":"success"}]}`))
	}))
	defer server.Close()
	source := &ExternalLiveSource{config: LiveSourceConfig{FinanceHistoryAPIURL: server.URL}, httpClient: server.Client()}
	b, err := source.financeHistory(context.Background(), CollectionState{})
	if err != nil {
		t.Fatal(err)
	}
	if len(b.Runs) != 2 || b.State.Status != "partial" || b.Runs[0].Status != "failed" || b.Runs[1].Verification != "not_checked" || strings.Contains(b.Runs[0].Message, "private") {
		t.Fatalf("incorrect sanitized audit mapping: %+v", b)
	}
	if b.Runs[0].StartedAt.Format(time.RFC3339) != "2026-09-04T16:00:14Z" {
		t.Fatal("owner UTC timestamp shifted")
	}
	o := testOperations(t)
	b.State.Provider = "finance"
	b.State.ObservedAt = time.Now().UTC()
	for i := 0; i < 2; i++ {
		if err = o.CommitBatch(context.Background(), b); err != nil {
			t.Fatal(err)
		}
	}
	if countTable(t, o, "runs") != 2 || countTable(t, o, "alerts") != 1 {
		t.Fatal("replay duplicated runs or failure alerts")
	}
}

func TestFinanceAPIFailsClosed(t *testing.T) {
	for _, body := range []string{
		`<html>not an API</html>`,
		`{"service":"other","recent_table_audits":[]}`,
		`{"service":"data-platform-finance"}`,
		`{"service":"data-platform-finance","recent_table_audits":null}`,
		`{"service":"data-platform-finance","recent_table_audits":[{"target_table":"salesforce_account","run_id":"r","status":"failed","started_at":"bad"}]}`,
		`{"service":"data-platform-finance","recent_table_audits":[{"target_table":"salesforce_account","run_id":"r","status":"failed","started_at":"2026-09-04 00:00:00","finished_at":"2026-09-03 00:00:00"}]}`,
	} {
		t.Run(body, func(t *testing.T) {
			server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(body)) }))
			defer server.Close()
			s := &ExternalLiveSource{config: LiveSourceConfig{FinanceHistoryAPIURL: server.URL}, httpClient: server.Client()}
			if _, err := s.financeHistory(context.Background(), CollectionState{}); err == nil {
				t.Fatal("invalid response accepted")
			}
		})
	}
	for _, binding := range []string{"http://example.test", "https://user:secret@example.test", "https://example.test?token=secret"} {
		s := &ExternalLiveSource{config: LiveSourceConfig{FinanceHistoryAPIURL: binding}}
		if _, err := s.financeHistory(context.Background(), CollectionState{}); err == nil {
			t.Fatal("unsafe binding accepted")
		}
	}
}

func TestFinanceAPIBindingCannotMixStores(t *testing.T) {
	o := testOperations(t)
	c := LiveSourceConfig{FinanceHistoryAPIURL: "https://finance-one.test"}
	if err := o.BindSourceConfig(c); err != nil {
		t.Fatal(err)
	}
	c.FinanceHistoryAPIURL = "https://finance-two.test"
	if err := o.BindSourceConfig(c); err == nil {
		t.Fatal("different Finance API mixed into history")
	}
}

func TestFinanceAPIOnboardingPreservesOtherProviders(t *testing.T) {
	o := testOperations(t)
	c := LiveSourceConfig{}
	if err := o.BindSourceConfig(c); err != nil {
		t.Fatal(err)
	}
	b := testBatch("succeeded", time.Now())
	b.State.Provider = "crm_load"
	b.Runs[0].Provider = "crm_load"
	b.Runs[0].Task = "crm_load"
	if err := o.CommitBatch(context.Background(), b); err != nil {
		t.Fatal(err)
	}
	c.FinanceHistoryAPIURL = "https://finance.test"
	if err := o.BindSourceConfig(c); err != nil {
		t.Fatal(err)
	}
	if err := o.BindSourceConfig(c); err != nil {
		t.Fatal(err)
	}
	if countTable(t, o, "runs") != 1 {
		t.Fatal("existing provider history lost")
	}
	other := testOperations(t)
	if err := other.BindSourceConfig(LiveSourceConfig{}); err != nil {
		t.Fatal(err)
	}
	if err := other.CommitBatch(context.Background(), testBatch("succeeded", time.Now())); err != nil {
		t.Fatal(err)
	}
	if err := other.BindSourceConfig(c); err == nil {
		t.Fatal("existing unbound Finance runs allowed source migration")
	}
}
