package executor

import (
	"testing"

	"github.com/everything-on-mysql/cassandra-on-mysql/pkg/cql/parser"
)

func TestBuildColumnMetaPositions(t *testing.T) {
	stmt, err := parser.NewParser(
		"CREATE TABLE ks.tbl (id int, bucket int, ts timestamp, name text, score int, PRIMARY KEY ((id, bucket), ts)) WITH CLUSTERING ORDER BY (ts DESC)",
	).Parse()
	if err != nil {
		t.Fatalf("failed to parse statement: %v", err)
	}

	createStmt, ok := stmt.(*parser.CreateTableStatement)
	if !ok {
		t.Fatalf("expected CreateTableStatement, got %T", stmt)
	}

	meta := buildColumnMeta(createStmt)
	if len(meta) != 5 {
		t.Fatalf("expected 5 columns, got %d", len(meta))
	}

	expected := map[string]columnMeta{
		"id":     {kind: "partition_key", position: 0, order: "NONE"},
		"bucket": {kind: "partition_key", position: 1, order: "NONE"},
		"ts":     {kind: "clustering", position: 0, order: "DESC"},
		"name":   {kind: "regular", position: -1, order: "NONE"},
		"score":  {kind: "regular", position: -1, order: "NONE"},
	}

	for _, col := range meta {
		exp, ok := expected[col.name]
		if !ok {
			t.Fatalf("unexpected column metadata for %q", col.name)
		}
		if col.kind != exp.kind || col.position != exp.position || col.order != exp.order {
			t.Fatalf(
				"column %s metadata mismatch: got kind=%s position=%d order=%s, want kind=%s position=%d order=%s",
				col.name,
				col.kind,
				col.position,
				col.order,
				exp.kind,
				exp.position,
				exp.order,
			)
		}
	}
}

func TestBuildColumnMetaStaticColumnPosition(t *testing.T) {
	stmt, err := parser.NewParser(
		"CREATE TABLE ks.tbl (id int, ts timestamp, note text static, PRIMARY KEY (id, ts))",
	).Parse()
	if err != nil {
		t.Fatalf("failed to parse statement: %v", err)
	}

	createStmt, ok := stmt.(*parser.CreateTableStatement)
	if !ok {
		t.Fatalf("expected CreateTableStatement, got %T", stmt)
	}

	meta := buildColumnMeta(createStmt)
	for _, col := range meta {
		if col.name == "note" {
			if col.kind != "static" || col.position != -1 {
				t.Fatalf("expected static column position -1, got kind=%s position=%d", col.kind, col.position)
			}
			return
		}
	}
	t.Fatal("static column note not found")
}

func TestBuildColumnMetaInlinePrimaryKey(t *testing.T) {
	stmt, err := parser.NewParser(
		"CREATE TABLE ks.tbl (id int PRIMARY KEY, name text, score int)",
	).Parse()
	if err != nil {
		t.Fatalf("failed to parse statement: %v", err)
	}

	createStmt, ok := stmt.(*parser.CreateTableStatement)
	if !ok {
		t.Fatalf("expected CreateTableStatement, got %T", stmt)
	}

	meta := buildColumnMeta(createStmt)
	expected := map[string]columnMeta{
		"id":    {kind: "partition_key", position: 0, order: "NONE"},
		"name":  {kind: "regular", position: -1, order: "NONE"},
		"score": {kind: "regular", position: -1, order: "NONE"},
	}
	for _, col := range meta {
		exp, ok := expected[col.name]
		if !ok {
			t.Fatalf("unexpected column metadata for %q", col.name)
		}
		if col.kind != exp.kind || col.position != exp.position || col.order != exp.order {
			t.Fatalf(
				"column %s metadata mismatch: got kind=%s position=%d order=%s, want kind=%s position=%d order=%s",
				col.name,
				col.kind,
				col.position,
				col.order,
				exp.kind,
				exp.position,
				exp.order,
			)
		}
	}
}
