package executor

import (
	"testing"

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

func TestValidateCounterTableDefinition(t *testing.T) {
	cases := []struct {
		name    string
		cql     string
		wantErr bool
	}{
		{
			name:    "counter in primary key",
			cql:     "CREATE TABLE ks.tbl (id counter PRIMARY KEY, cnt counter)",
			wantErr: true,
		},
		{
			name:    "mixed counter and non-counter",
			cql:     "CREATE TABLE ks.tbl (id int PRIMARY KEY, cnt counter, name text)",
			wantErr: true,
		},
		{
			name:    "all counters ok",
			cql:     "CREATE TABLE ks.tbl (id int PRIMARY KEY, cnt counter)",
			wantErr: false,
		},
		{
			name:    "no counters ok",
			cql:     "CREATE TABLE ks.tbl (id int PRIMARY KEY, name text)",
			wantErr: false,
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			stmt := mustParseStatement(t, tc.cql)
			createStmt, ok := stmt.(*parser.CreateTableStatement)
			if !ok {
				t.Fatalf("expected create table statement, got %T", stmt)
			}
			err := validateCounterTableDefinition(createStmt)
			if tc.wantErr && err == nil {
				t.Fatalf("expected error")
			}
			if !tc.wantErr && err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
		})
	}
}

func TestValidateCounterTableAlterAdd(t *testing.T) {
	pk := []string{"id"}
	cases := []struct {
		name        string
		columnTypes map[string]string
		newType     string
		wantErr     bool
	}{
		{
			name: "add counter to non-counter table",
			columnTypes: map[string]string{
				"id":   "int",
				"name": "text",
			},
			newType: "counter",
			wantErr: true,
		},
		{
			name: "add non-counter to counter table",
			columnTypes: map[string]string{
				"id":  "int",
				"cnt": "counter",
			},
			newType: "text",
			wantErr: true,
		},
		{
			name: "add counter to counter table",
			columnTypes: map[string]string{
				"id":  "int",
				"cnt": "counter",
			},
			newType: "counter",
			wantErr: false,
		},
		{
			name: "add counter to pk-only table",
			columnTypes: map[string]string{
				"id": "int",
			},
			newType: "counter",
			wantErr: false,
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			err := validateCounterTableAlterAdd(tc.newType, tc.columnTypes, pk)
			if tc.wantErr && err == nil {
				t.Fatalf("expected error")
			}
			if !tc.wantErr && err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
		})
	}
}

func TestTableHasCounterColumns(t *testing.T) {
	if tableHasCounterColumns(map[string]string{"id": "int", "cnt": "counter"}) != true {
		t.Fatalf("expected counter detection")
	}
	if tableHasCounterColumns(map[string]string{"id": "int", "name": "text"}) != false {
		t.Fatalf("expected no counter detection")
	}
}
