package catalogtenant

import (
	"strings"
	"testing"

	"github.com/pingcap/tidb/pkg/parser"
	_ "github.com/pingcap/tidb/pkg/parser/test_driver"
)

func TestSchemaParsesWithTiDB(t *testing.T) {
	sqlParser := parser.New()
	for _, statement := range SchemaStatementsForTest() {
		if _, _, err := sqlParser.Parse(statement, "", ""); err != nil {
			t.Fatalf("tenant authority schema does not parse: %v\n%s", err, statement)
		}
	}
}

func TestSchemaOwnsOnlyTenantAuthorityCommandCurrentAndHistory(t *testing.T) {
	joined := strings.Join(SchemaStatementsForTest(), "\n")
	for _, required := range []string{
		"_System_CatalogTenantAuthorityFence",
		"_System_CatalogTenantAuthorityCommand",
		"_System_CatalogTenantNamespaceReservation",
		"_System_CatalogTenantNamespaceHistory",
		"_System_CatalogTenantOrgNamespaceBinding",
		"_System_CatalogTenantOrgNamespaceBindingHistory",
		"_System_CatalogTenantLayoutBundleSlot",
		"_System_CatalogTenantLayoutBundleSlotHistory",
		"VARBINARY(255)",
		"VARBINARY(128)",
		"ACTIVE",
		"TOMBSTONE",
		"RequestDigest",
		"ObservedNamespace",
		"ObservedBinding",
	} {
		if !strings.Contains(joined, required) {
			t.Fatalf("tenant authority schema is missing %q", required)
		}
	}
	for _, forbidden := range []string{
		"LayoutBundleRevision",
		"LayoutAssignment",
		"ServingSelector",
		"AuthorityEvidence",
		"VerificationReceipt",
		"DELETE FROM",
	} {
		if strings.Contains(joined, forbidden) {
			t.Fatalf("tenant authority schema leaked %q", forbidden)
		}
	}
}

func TestSchemaStatementsAreDefensive(t *testing.T) {
	first := SchemaStatementsForTest()
	first[0] = "changed"
	if SchemaStatementsForTest()[0] == "changed" {
		t.Fatal("SchemaStatementsForTest returned shared storage")
	}
}
