package models

import "testing"

func TestNormalizeObjectReadSourceConfigCanonicalizesWhitespace(t *testing.T) {
	cfg, err := NormalizeObjectReadSourceConfig(&ObjectReadSourceConfig{
		Kind:          " physical_table ",
		PhysicalTable: " _System_RecordType ",
	})
	if err != nil {
		t.Fatalf("NormalizeObjectReadSourceConfig() error = %v", err)
	}
	if cfg.Kind != "physical_table" {
		t.Fatalf("NormalizeObjectReadSourceConfig().Kind = %q, want %q", cfg.Kind, "physical_table")
	}
	if cfg.PhysicalTable != "_System_RecordType" {
		t.Fatalf("NormalizeObjectReadSourceConfig().PhysicalTable = %q, want %q", cfg.PhysicalTable, "_System_RecordType")
	}
}

func TestResolveReadSourceTableDefaultsToAPIName(t *testing.T) {
	obj := &ObjectMetadata{APIName: "RecordType"}
	got, err := obj.ResolveReadSourceTable()
	if err != nil {
		t.Fatalf("ResolveReadSourceTable() error = %v", err)
	}
	if got != "RecordType" {
		t.Fatalf("ResolveReadSourceTable() = %q, want %q", got, "RecordType")
	}
}

func TestCanonicalObjectReadSourceJSONRejectsMalformedDeclaration(t *testing.T) {
	_, err := CanonicalObjectReadSourceJSON(&ObjectReadSourceConfig{Kind: "view", PhysicalTable: "_System_RecordType"})
	if err == nil {
		t.Fatal("CanonicalObjectReadSourceJSON() = nil err, want failure")
	}
}

func TestResolveReadSourceTableAcceptsPhysicalTable(t *testing.T) {
	obj := &ObjectMetadata{
		APIName: "RecordType",
		ReadSource: &ObjectReadSourceConfig{
			Kind:          "physical_table",
			PhysicalTable: "_System_RecordType",
		},
	}
	got, err := obj.ResolveReadSourceTable()
	if err != nil {
		t.Fatalf("ResolveReadSourceTable() error = %v", err)
	}
	if got != "_System_RecordType" {
		t.Fatalf("ResolveReadSourceTable() = %q, want %q", got, "_System_RecordType")
	}
}

func TestResolveReadSourceTableRejectsMalformedDeclaration(t *testing.T) {
	cases := []struct {
		name string
		cfg  *ObjectReadSourceConfig
	}{
		{
			name: "missing_kind",
			cfg:  &ObjectReadSourceConfig{PhysicalTable: "_System_RecordType"},
		},
		{
			name: "unsupported_kind",
			cfg:  &ObjectReadSourceConfig{Kind: "view", PhysicalTable: "_System_RecordType"},
		},
		{
			name: "missing_table",
			cfg:  &ObjectReadSourceConfig{Kind: "physical_table"},
		},
		{
			name: "unsafe_identifier",
			cfg:  &ObjectReadSourceConfig{Kind: "physical_table", PhysicalTable: "_System_RecordType;DROP"},
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			obj := &ObjectMetadata{APIName: "RecordType", ReadSource: tc.cfg}
			if _, err := obj.ResolveReadSourceTable(); err == nil {
				t.Fatal("ResolveReadSourceTable() = nil err, want failure")
			}
		})
	}
}
