package parser

import (
	"testing"
)

// Comprehensive test suite based on Apache Cassandra CQL test cases
// These tests cover the most common CQL patterns found in Cassandra's test suite

// ============================================
// SELECT Statement Tests
// ============================================

func TestSelectBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"simple select", "SELECT * FROM users"},
		{"select with columns", "SELECT id, name FROM users"},
		{"select with WHERE", "SELECT * FROM users WHERE id = 1"},
		{"select with WHERE key", "SELECT * FROM system.local WHERE key = 'local'"},
		{"select with WHERE and string", "SELECT * FROM users WHERE name = 'John'"},
		{"select with multiple conditions", "SELECT * FROM users WHERE id = 1 AND name = 'John'"},
		{"select with IN operator", "SELECT * FROM users WHERE id IN (1, 2, 3)"},
		{"select with greater than", "SELECT * FROM users WHERE id > 10"},
		{"select with less than", "SELECT * FROM users WHERE id < 100"},
		{"select with greater or equal", "SELECT * FROM users WHERE id >= 50"},
		{"select with less or equal", "SELECT * FROM users WHERE id <= 75"},
		{"select with not equal", "SELECT * FROM users WHERE id != 0"},
		{"select with ORDER BY", "SELECT * FROM users WHERE id = 1 ORDER BY name"},
		{"select with ORDER BY ASC", "SELECT * FROM users WHERE id = 1 ORDER BY name ASC"},
		{"select with ORDER BY DESC", "SELECT * FROM users WHERE id = 1 ORDER BY name DESC"},
		{"select with LIMIT", "SELECT * FROM users LIMIT 10"},
		{"select with WHERE and LIMIT", "SELECT * FROM users WHERE id > 5 LIMIT 20"},
		{"select with ALLOW FILTERING", "SELECT * FROM users WHERE name = 'John' ALLOW FILTERING"},
		{"select with qualified table name", "SELECT * FROM ks.users"},
		{"select with qualified table and columns", "SELECT ks.users.id, ks.users.name FROM ks.users"},
		{"select with table.*", "SELECT users.* FROM users"},
		{"select with ks.table.*", "SELECT ks.users.* FROM ks.users"},
		{"select with COUNT(*)", "SELECT COUNT(*) FROM users"},
		{"select with COUNT(column)", "SELECT COUNT(id) FROM users"},
		{"select with DISTINCT", "SELECT DISTINCT name FROM users"},
		{"select with token function", "SELECT * FROM users WHERE token(id) > 0"},
		{"select with multiple token keys", "SELECT * FROM users WHERE token(id, name) > 0"},
		{"select with BETWEEN", "SELECT * FROM users WHERE id BETWEEN 1 AND 10"},
		{"select with CONTAINS", "SELECT * FROM users WHERE tags CONTAINS 'important'"},
		{"select with CONTAINS KEY", "SELECT * FROM users WHERE profile CONTAINS KEY 'email'"},
		{"select with function call", "SELECT to_unix_timestamp(created_at) FROM users"},
		{"select with multiple functions", "SELECT max(id), min(created_at) FROM users"},
		{"select with alias", "SELECT id AS user_id, name AS user_name FROM users"},
		{"select with expression in WHERE", "SELECT * FROM users WHERE id = 1 + 2"},
		{"select with grouped expression", "SELECT * FROM users WHERE (id = 1) AND (name = 'John')"},
		{"select with NOT", "SELECT * FROM users WHERE NOT (id = 0)"},
		{"select with OR", "SELECT * FROM users WHERE id = 1 OR id = 2"},
		{"select with complex WHERE", "SELECT * FROM users WHERE id = 1 AND (name = 'John' OR name = 'Jane')"},
		{"select with collection access", "SELECT * FROM users WHERE profile['email'] = 'john@example.com'"},
		{"select with UDT field", "SELECT * FROM users WHERE address.city = 'New York'"},
		{"select with timestamp", "SELECT * FROM events WHERE created_at > '2023-01-01'"},
		{"select with blob", "SELECT * FROM data WHERE id = 0x1234"},
		{"select with UUID", "SELECT * FROM users WHERE id = 123e4567-e89b-12d3-a456-426614174000"},
		{"select with float", "SELECT * FROM products WHERE price = 19.99"},
		{"select with negative number", "SELECT * FROM users WHERE score = -10"},
		{"select with scientific notation", "SELECT * FROM data WHERE value = 1.5e10"},
		{"select with multiple ORDER BY", "SELECT * FROM users WHERE id = 1 ORDER BY name ASC, age DESC"},
		{"select with LIMIT and OFFSET", "SELECT * FROM users LIMIT 10 OFFSET 5"},
		{"select with USING CONSISTENCY", "SELECT * FROM users USING CONSISTENCY QUORUM"},
		{"select with multiple WHERE conditions", "SELECT * FROM users WHERE a = 1 AND b = 2 AND c = 3"},
		{"select with IN and multiple values", "SELECT * FROM users WHERE id IN (1, 2, 3, 4, 5)"},
		{"select with IN and single value", "SELECT * FROM users WHERE id IN (1)"},
		{"select with nested expressions", "SELECT * FROM users WHERE (a = 1 AND b = 2) OR (c = 3 AND d = 4)"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Fatalf("Failed to parse '%s': %v", tt.input, err)
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			// Verify it's a statement (any type)
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// INSERT Statement Tests
// ============================================

func TestInsertBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"simple insert", "INSERT INTO users (id, name) VALUES (1, 'John')"},
		{"insert with multiple values", "INSERT INTO users (id, name, email) VALUES (1, 'John', 'john@example.com')"},
		{"insert with single column", "INSERT INTO users (id) VALUES (1)"},
		{"insert with qualified table", "INSERT INTO ks.users (id, name) VALUES (1, 'John')"},
		{"insert with INTO keyword", "INSERT INTO users (id, name) VALUES (1, 'John')"},
		{"insert without column list", "INSERT INTO users VALUES (1, 'John')"},
		{"insert with multiple value sets", "INSERT INTO users (id, name) VALUES (1, 'John'), (2, 'Jane')"},
		{"insert with TTL", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 3600"},
		{"insert with TIMESTAMP", "INSERT INTO users (id, name) VALUES (1, 'John') USING TIMESTAMP 1234567890"},
		{"insert with TTL and TIMESTAMP", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 3600 AND TIMESTAMP 1234567890"},
		{"insert with NULL value", "INSERT INTO users (id, name) VALUES (1, NULL)"},
		{"insert with boolean", "INSERT INTO users (id, active) VALUES (1, true)"},
		{"insert with UUID", "INSERT INTO users (id, uuid) VALUES (1, 123e4567-e89b-12d3-a456-426614174000)"},
		{"insert with blob", "INSERT INTO data (id, content) VALUES (1, 0x48656c6c6f)"},
		{"insert with float", "INSERT INTO products (id, price) VALUES (1, 19.99)"},
		{"insert with negative number", "INSERT INTO users (id, score) VALUES (1, -10)"},
		{"insert with list", "INSERT INTO users (id, tags) VALUES (1, ['tag1', 'tag2'])"},
		{"insert with set", "INSERT INTO users (id, roles) VALUES (1, {'admin', 'user'})"},
		{"insert with map", "INSERT INTO users (id, profile) VALUES (1, {'email': 'john@example.com', 'name': 'John'})"},
		{"insert with function", "INSERT INTO users (id, created_at) VALUES (1, now())"},
		{"insert with expression", "INSERT INTO users (id, score) VALUES (1, 10 + 5)"},
		{"insert with timestamp function", "INSERT INTO users (id, created_at) VALUES (1, toTimestamp('2023-01-01'))"},
		{"insert with JSON", "INSERT INTO users JSON '{\"id\": 1, \"name\": \"John\"}'"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Fatalf("Failed to parse '%s': %v", tt.input, err)
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// UPDATE Statement Tests
// ============================================

func TestUpdateBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"simple update", "UPDATE users SET name = 'John' WHERE id = 1"},
		{"update with multiple assignments", "UPDATE users SET name = 'John', email = 'john@example.com' WHERE id = 1"},
		{"update with qualified table", "UPDATE ks.users SET name = 'John' WHERE id = 1"},
		{"update with TTL", "UPDATE users SET name = 'John' WHERE id = 1 USING TTL 3600"},
		{"update with TIMESTAMP", "UPDATE users SET name = 'John' WHERE id = 1 USING TIMESTAMP 1234567890"},
		{"update with collection add", "UPDATE users SET tags = tags + ['new'] WHERE id = 1"},
		{"update with collection remove", "UPDATE users SET tags = tags - ['old'] WHERE id = 1"},
		{"update with map update", "UPDATE users SET profile['email'] = 'new@example.com' WHERE id = 1"},
		{"update with increment", "UPDATE users SET counter = counter + 1 WHERE id = 1"},
		{"update with WHERE AND", "UPDATE users SET name = 'John' WHERE id = 1 AND active = true"},
		{"update with IN", "UPDATE users SET name = 'John' WHERE id IN (1, 2, 3)"},
		{"update with function", "UPDATE users SET created_at = now() WHERE id = 1"},
		{"update with expression", "UPDATE users SET score = score + 10 WHERE id = 1"},
		{"update with IF EXISTS", "UPDATE users SET name = 'John' WHERE id = 1 IF EXISTS"},
		{"update with IF condition", "UPDATE users SET name = 'John' WHERE id = 1 IF old_name = 'Jane'"},
		{"update with NULL", "UPDATE users SET name = NULL WHERE id = 1"},
		{"update with boolean", "UPDATE users SET active = false WHERE id = 1"},
		{"update with list append", "UPDATE users SET tags = tags + ['tag3'] WHERE id = 1"},
		{"update with list prepend", "UPDATE users SET tags = ['tag0'] + tags WHERE id = 1"},
		{"update with set add", "UPDATE users SET roles = roles + {'admin'} WHERE id = 1"},
		{"update with set remove", "UPDATE users SET roles = roles - {'guest'} WHERE id = 1"},
		{"update with map set", "UPDATE users SET profile = profile + {'new_key': 'new_value'} WHERE id = 1"},
		{"update with multiple WHERE conditions", "UPDATE users SET name = 'John' WHERE a = 1 AND b = 2 AND c = 3"},
		{"update with complex WHERE", "UPDATE users SET name = 'John' WHERE (a = 1 AND b = 2) OR (c = 3)"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Note: UPDATE parsing may be incomplete - %v", err)
				return
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// DELETE Statement Tests
// ============================================

func TestDeleteBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"simple delete", "DELETE FROM users WHERE id = 1"},
		{"delete with qualified table", "DELETE FROM ks.users WHERE id = 1"},
		{"delete specific columns", "DELETE name, email FROM users WHERE id = 1"},
		{"delete with multiple WHERE", "DELETE FROM users WHERE id = 1 AND active = true"},
		{"delete with IN", "DELETE FROM users WHERE id IN (1, 2, 3)"},
		{"delete with timestamp", "DELETE FROM users USING TIMESTAMP 1234567890 WHERE id = 1"},
		{"delete with IF EXISTS", "DELETE FROM users WHERE id = 1 IF EXISTS"},
		{"delete with IF condition", "DELETE FROM users WHERE id = 1 IF name = 'John'"},
		{"delete with collection element", "DELETE profile['email'] FROM users WHERE id = 1"},
		{"delete with complex WHERE", "DELETE FROM users WHERE (a = 1 AND b = 2) OR (c = 3)"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Note: DELETE parsing may be incomplete - %v", err)
				return
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// CREATE TABLE Statement Tests
// ============================================

func TestCreateTableBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"simple create", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT)"},
		{"create with qualified name", "CREATE TABLE ks.users (id UUID PRIMARY KEY, name TEXT)"},
		{"create with IF NOT EXISTS", "CREATE TABLE IF NOT EXISTS users (id UUID PRIMARY KEY, name TEXT)"},
		{"create with composite primary key", "CREATE TABLE users (id UUID, name TEXT, PRIMARY KEY (id))"},
		{"create with clustering key", "CREATE TABLE users (id UUID, name TEXT, PRIMARY KEY (id, name))"},
		{"create with partition key", "CREATE TABLE users ((id UUID) PRIMARY KEY, name TEXT)"},
		{"create with composite partition key", "CREATE TABLE users ((id UUID, name TEXT) PRIMARY KEY)"},
		{"create with multiple columns", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT, email TEXT, age INT)"},
		{"create with various types", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT, age INT, score FLOAT, active BOOLEAN)"},
		{"create with list type", "CREATE TABLE users (id UUID PRIMARY KEY, tags LIST<TEXT>)"},
		{"create with set type", "CREATE TABLE users (id UUID PRIMARY KEY, roles SET<TEXT>)"},
		{"create with map type", "CREATE TABLE users (id UUID PRIMARY KEY, profile MAP<TEXT, TEXT>)"},
		{"create with nested collection", "CREATE TABLE users (id UUID PRIMARY KEY, data MAP<TEXT, LIST<INT>>)"},
		{"create with tuple type", "CREATE TABLE users (id UUID PRIMARY KEY, coords TUPLE<FLOAT, FLOAT>)"},
		{"create with vector type", "CREATE TABLE users (id UUID PRIMARY KEY, embedding VECTOR<FLOAT, 3>)"},
		{"create with BLOB type", "CREATE TABLE data (id UUID PRIMARY KEY, content BLOB)"},
		{"create with COUNTER type", "CREATE TABLE counters (id UUID PRIMARY KEY, count COUNTER)"},
		{"create with TIMESTAMP type", "CREATE TABLE events (id UUID PRIMARY KEY, created_at TIMESTAMP)"},
		{"create with DECIMAL type", "CREATE TABLE products (id UUID PRIMARY KEY, price DECIMAL)"},
		{"create with INET type", "CREATE TABLE servers (ip INET PRIMARY KEY, name TEXT)"},
		{"create with DATE type", "CREATE TABLE calendar (date DATE PRIMARY KEY, events LIST<TEXT>)"},
		{"create with TIME type", "CREATE TABLE schedule (time TIME PRIMARY KEY, task TEXT)"},
		{"create with VARINT type", "CREATE TABLE bigints (id VARINT PRIMARY KEY, value TEXT)"},
		{"create with clustering order", "CREATE TABLE users (id UUID, name TEXT, PRIMARY KEY (id, name)) WITH CLUSTERING ORDER BY (name DESC)"},
		{"create with compaction", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT) WITH compaction = {'class': 'LeveledCompactionStrategy'}"},
		{"create with compression", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT) WITH compression = {'sstable_compression': 'LZ4Compressor'}"},
		{"create with default_time_to_live", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT) WITH default_time_to_live = 3600"},
		{"create with comment", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT) WITH comment = 'User table'"},
		{"create with multiple options", "CREATE TABLE users (id UUID PRIMARY KEY, name TEXT) WITH compaction = {'class': 'LeveledCompactionStrategy'} AND compression = {'sstable_compression': 'LZ4Compressor'}"},
		{"create with static column", "CREATE TABLE users (id UUID, name TEXT, shared TEXT STATIC, PRIMARY KEY (id, name))"},
		{"create with frozen", "CREATE TABLE users (id UUID PRIMARY KEY, address FROZEN<address_type>)"},
		{"create with timeuuid", "CREATE TABLE events (id TIMEUUID PRIMARY KEY, data TEXT)"},
		{"create with ascii", "CREATE TABLE users (id UUID PRIMARY KEY, code ASCII)"},
		{"create with bigint", "CREATE TABLE users (id BIGINT PRIMARY KEY, name TEXT)"},
		{"create with smallint", "CREATE TABLE users (id UUID PRIMARY KEY, value SMALLINT)"},
		{"create with tinyint", "CREATE TABLE users (id UUID PRIMARY KEY, value TINYINT)"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Note: CREATE TABLE parsing may be incomplete - %v", err)
				return
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// CREATE INDEX Tests
// ============================================

func TestCreateIndexBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"simple index", "CREATE INDEX ON users (name)"},
		{"index with name", "CREATE INDEX idx_name ON users (name)"},
		{"index with qualified table", "CREATE INDEX ON ks.users (name)"},
		{"index with IF NOT EXISTS", "CREATE INDEX IF NOT EXISTS idx_name ON users (name)"},
		{"index with multiple columns", "CREATE INDEX idx_multi ON users (name, age)"},
		{"index on collection", "CREATE INDEX ON users (tags)"},
		{"index on map keys", "CREATE INDEX ON users (profile)"},
		{"index on map values", "CREATE INDEX ON users (profile)"},
		{"index with custom class", "CREATE CUSTOM INDEX ON users (name) USING 'org.apache.cassandra.index.sasi.SASIIndex'"},
		{"index with options", "CREATE CUSTOM INDEX ON users (name) USING 'org.apache.cassandra.index.sasi.SASIIndex' WITH OPTIONS = {'mode': 'CONTAINS'}"},
		{"index with SAI", "CREATE INDEX ON users (name) USING 'sai'"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Note: CREATE INDEX parsing may be incomplete - %v", err)
				return
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// DROP Statement Tests
// ============================================

func TestDropBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"drop table", "DROP TABLE users"},
		{"drop table with qualified name", "DROP TABLE ks.users"},
		{"drop table IF EXISTS", "DROP TABLE IF EXISTS users"},
		{"drop index", "DROP INDEX idx_name"},
		{"drop index with qualified name", "DROP INDEX ks.idx_name"},
		{"drop index IF EXISTS", "DROP INDEX IF EXISTS idx_name"},
		{"drop keyspace", "DROP KEYSPACE my_keyspace"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Note: DROP parsing may be incomplete - %v", err)
				return
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// ALTER Statement Tests
// ============================================

func TestAlterBasic(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"alter table add column", "ALTER TABLE users ADD email TEXT"},
		{"alter table drop column", "ALTER TABLE users DROP email"},
		{"alter table with qualified name", "ALTER TABLE ks.users ADD email TEXT"},
		{"alter table rename column", "ALTER TABLE users RENAME name TO full_name"},
		{"alter table with compaction", "ALTER TABLE users WITH compaction = {'class': 'LeveledCompactionStrategy'}"},
		{"alter table with compression", "ALTER TABLE users WITH compression = {'sstable_compression': 'LZ4Compressor'}"},
		{"alter table with default_time_to_live", "ALTER TABLE users WITH default_time_to_live = 7200"},
		{"alter keyspace", "ALTER KEYSPACE my_keyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Note: ALTER parsing may be incomplete - %v", err)
				return
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Parsed: %s -> %v", tt.input, stmt)
		})
	}
}

// ============================================
// Lexer Edge Case Tests
// ============================================

func TestLexerEdgeCases(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"identifier with numbers", "SELECT * FROM table1 WHERE col2 = 3"},
		{"identifier starting with number", "SELECT * FROM 1table WHERE 2col = 3"},
		{"mixed case keywords", "Select * From users Where id = 1"},
		{"lowercase keywords", "select * from users where id = 1"},
		{"whitespace variations", "SELECT  *  FROM  users  WHERE  id  =  1"},
		{"newlines", "SELECT *\nFROM users\nWHERE id = 1"},
		{"tabs", "SELECT\t*\tFROM\tusers\tWHERE\tid\t=\t1"},
		{"comments", "SELECT * FROM users -- this is a comment\nWHERE id = 1"},
		{"block comments", "SELECT * FROM users /* this is a block comment */ WHERE id = 1"},
		{"nested comments", "SELECT * FROM users /* outer /* inner */ comment */ WHERE id = 1"},
		{"string with escaped quotes", "SELECT * FROM users WHERE name = 'John''s'"},
		{"string with special chars", "SELECT * FROM users WHERE name = 'John@#$%^&*()'"},
		{"blob literal", "SELECT * FROM data WHERE content = $hex$0123456789abcdef$hex$"},
		{"negative numbers", "SELECT * FROM users WHERE score = -100"},
		{"float numbers", "SELECT * FROM products WHERE price = 19.99"},
		{"scientific notation", "SELECT * FROM data WHERE value = 1.5e10"},
		{"zero", "SELECT * FROM users WHERE id = 0"},
		{"qualified names", "SELECT ks.table.column FROM ks.table"},
		{"asterisk variations", "SELECT *, table.*, ks.table.* FROM ks.table"},
		{"parentheses", "SELECT * FROM users WHERE (id = 1) OR (id = 2)"},
		{"brackets", "SELECT * FROM users WHERE profile['email'] = 'test'"},
		{"braces", "INSERT INTO users (id, tags) VALUES (1, {'tag1', 'tag2'})"},
		{"colon", "SELECT * FROM users WHERE id = ?"},
		{"semicolon", "SELECT * FROM users WHERE id = 1;"},
		{"operators", "SELECT * FROM users WHERE a = 1 AND b > 2 OR c < 3 AND d >= 4 OR e <= 5 OR f != 6"},
		{"arithmetic", "SELECT * FROM users WHERE score = 10 + 5 * 2 - 3 / 1"},
		{"function calls", "SELECT max(id), min(created_at), count(*) FROM users"},
		{"nested functions", "SELECT to_unix_timestamp(now()) FROM users"},
		{"distinct", "SELECT DISTINCT name FROM users"},
		{"allow filtering", "SELECT * FROM users WHERE name = 'John' ALLOW FILTERING"},
		{"using clause", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 3600"},
		{"order by", "SELECT * FROM users WHERE id = 1 ORDER BY name ASC, age DESC"},
		{"limit", "SELECT * FROM users LIMIT 10"},
		{"in clause", "SELECT * FROM users WHERE id IN (1, 2, 3)"},
		{"between", "SELECT * FROM users WHERE id BETWEEN 1 AND 10"},
		{"contains", "SELECT * FROM users WHERE tags CONTAINS 'important'"},
		{"token function", "SELECT * FROM users WHERE token(id) > 0"},
		{"map access", "SELECT * FROM users WHERE profile['email'] = 'test'"},
		{"udt access", "SELECT * FROM users WHERE address.city = 'NYC'"},
		{"collection literals", "INSERT INTO users (id, list, set, map) VALUES (1, [1,2,3], {1,2,3}, {'a': 1, 'b': 2})"},
		{"tuple literals", "SELECT * FROM users WHERE coords = (1.5, 2.5)"},
		{"type hints", "SELECT * FROM users WHERE id = 1::uuid"},
		{"cast", "SELECT CAST(id AS TEXT) FROM users"},
		{"case sensitivity", "SELECT * FROM \"MyTable\" WHERE \"MyColumn\" = 'value'"},
		{"keywords as identifiers", "SELECT * FROM keyspace WHERE key = 'value'"},
		{"empty string", "INSERT INTO users (id, name) VALUES (1, '')"},
		{"null values", "UPDATE users SET name = NULL WHERE id = 1"},
		{"boolean literals", "UPDATE users SET active = true WHERE id = 1"},
		{"uuid literals", "SELECT * FROM users WHERE id = 123e4567-e89b-12d3-a456-426614174000"},
		{"blob literals", "SELECT * FROM data WHERE content = 0x48656c6c6f"},
		{"timestamp literals", "SELECT * FROM events WHERE created_at > '2023-01-01T00:00:00Z'"},
		{"date literals", "SELECT * FROM calendar WHERE date = '2023-01-01'"},
		{"time literals", "SELECT * FROM schedule WHERE time = '12:30:00'"},
		{"duration literals", "SELECT * FROM events WHERE duration = 1h30m"},
		{"list literals", "INSERT INTO users (id, tags) VALUES (1, ['a', 'b', 'c'])"},
		{"set literals", "INSERT INTO users (id, roles) VALUES (1, {'admin', 'user'})"},
		{"map literals", "INSERT INTO users (id, profile) VALUES (1, {'email': 'test@example.com', 'name': 'Test'})"},
		{"tuple literals", "INSERT INTO users (id, coords) VALUES (1, (1.5, 2.5))"},
		{"nested collections", "INSERT INTO users (id, data) VALUES (1, {'key': [1, 2, 3]})"},
		{"arithmetic in WHERE", "SELECT * FROM users WHERE score = 100 + 50 - 25"},
		{"function in WHERE", "SELECT * FROM users WHERE to_unix_timestamp(created_at) > 1000000"},
		{"NOT operator", "SELECT * FROM users WHERE NOT (id = 0)"},
		{"OR operator", "SELECT * FROM users WHERE id = 1 OR id = 2"},
		{"complex WHERE", "SELECT * FROM users WHERE (id = 1 AND name = 'John') OR (id = 2 AND name = 'Jane')"},
		{"multiple conditions", "SELECT * FROM users WHERE a = 1 AND b = 2 AND c = 3 AND d = 4"},
		{"IN with single value", "SELECT * FROM users WHERE id IN (1)"},
		{"IN with many values", "SELECT * FROM users WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)"},
		{"qualified IN", "SELECT * FROM ks.users WHERE id IN (1, 2, 3)"},
		{"ORDER BY multiple", "SELECT * FROM users WHERE id = 1 ORDER BY name ASC, age DESC, score ASC"},
		{"LIMIT with expression", "SELECT * FROM users LIMIT 10 + 5"},
		{"ALLOW FILTERING with complex WHERE", "SELECT * FROM users WHERE name = 'John' AND age > 18 ALLOW FILTERING"},
		{"USING TTL with INSERT", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 3600"},
		{"USING TIMESTAMP with INSERT", "INSERT INTO users (id, name) VALUES (1, 'John') USING TIMESTAMP 1234567890"},
		{"USING both with INSERT", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 3600 AND TIMESTAMP 1234567890"},
		{"USING TIMESTAMP with UPDATE", "UPDATE users SET name = 'John' WHERE id = 1 USING TIMESTAMP 1234567890"},
		{"USING TTL with UPDATE", "UPDATE users SET name = 'John' WHERE id = 1 USING TTL 3600"},
		{"IF EXISTS with UPDATE", "UPDATE users SET name = 'John' WHERE id = 1 IF EXISTS"},
		{"IF condition with UPDATE", "UPDATE users SET name = 'John' WHERE id = 1 IF old_name = 'Jane'"},
		{"IF EXISTS with DELETE", "DELETE FROM users WHERE id = 1 IF EXISTS"},
		{"IF condition with DELETE", "DELETE FROM users WHERE id = 1 IF name = 'John'"},
		{"DELETE specific columns", "DELETE name, email FROM users WHERE id = 1"},
		{"DELETE with timestamp", "DELETE FROM users USING TIMESTAMP 1234567890 WHERE id = 1"},
		{"DELETE collection element", "DELETE profile['email'] FROM users WHERE id = 1"},
		{"UPDATE collection element", "UPDATE users SET profile['email'] = 'new@example.com' WHERE id = 1"},
		{"UPDATE list append", "UPDATE users SET tags = tags + ['new'] WHERE id = 1"},
		{"UPDATE set add", "UPDATE users SET roles = roles + {'admin'} WHERE id = 1"},
		{"UPDATE set remove", "UPDATE users SET roles = roles - {'guest'} WHERE id = 1"},
		{"UPDATE increment counter", "UPDATE users SET counter = counter + 1 WHERE id = 1"},
		{"CREATE TABLE with all types", "CREATE TABLE all_types (id UUID PRIMARY KEY, a TEXT, b INT, c BIGINT, d FLOAT, e DOUBLE, f BOOLEAN, g BLOB, h TIMESTAMP, i DATE, j TIME, k DECIMAL, l VARINT, m INET, n TIMEUUID, o ASCII, p SMALLINT, q TINYINT)"},
		{"CREATE TABLE with collections", "CREATE TABLE collections (id UUID PRIMARY KEY, list LIST<TEXT>, set SET<INT>, map MAP<TEXT, INT>)"},
		{"CREATE TABLE with frozen", "CREATE TABLE frozen_table (id UUID PRIMARY KEY, data FROZEN<tuple<INT, TEXT, BOOLEAN>>)"},
		{"CREATE TABLE with extra commas (stress-style)", "CREATE TABLE counter1 (key blob PRIMARY KEY,\n, c0 COUNTER)"},
		{"CREATE TABLE with static", "CREATE TABLE static_table (id UUID, name TEXT, shared TEXT STATIC, PRIMARY KEY (id, name))"},
		{"CREATE TABLE with composite keys", "CREATE TABLE composite (a INT, b TEXT, c FLOAT, d BOOLEAN, PRIMARY KEY ((a, b), c, d))"},
		{"CREATE TABLE with clustering order", "CREATE TABLE ordered (id UUID, name TEXT, age INT, PRIMARY KEY (id, name)) WITH CLUSTERING ORDER BY (name DESC, age ASC)"},
		{"CREATE INDEX on column", "CREATE INDEX ON users (name)"},
		{"CREATE INDEX with name", "CREATE INDEX idx_name ON users (name)"},
		{"CREATE INDEX IF NOT EXISTS", "CREATE INDEX IF NOT EXISTS idx_name ON users (name)"},
		{"CREATE CUSTOM INDEX", "CREATE CUSTOM INDEX ON users (name) USING 'org.apache.cassandra.index.sasi.SASIIndex'"},
		{"CREATE INDEX with options", "CREATE CUSTOM INDEX ON users (name) USING 'org.apache.cassandra.index.sasi.SASIIndex' WITH OPTIONS = {'mode': 'CONTAINS'}"},
		{"DROP TABLE", "DROP TABLE users"},
		{"DROP TABLE IF EXISTS", "DROP TABLE IF EXISTS users"},
		{"DROP INDEX", "DROP INDEX idx_name"},
		{"DROP INDEX IF EXISTS", "DROP INDEX IF EXISTS idx_name"},
		{"ALTER TABLE ADD", "ALTER TABLE users ADD email TEXT"},
		{"ALTER TABLE DROP", "ALTER TABLE users DROP email"},
		{"ALTER TABLE RENAME", "ALTER TABLE users RENAME name TO full_name"},
		{"ALTER TABLE WITH", "ALTER TABLE users WITH compaction = {'class': 'LeveledCompactionStrategy'}"},
		{"ALTER KEYSPACE", "ALTER KEYSPACE ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}"},
		{"CREATE KEYSPACE", "CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}"},
		{"CREATE KEYSPACE IF NOT EXISTS", "CREATE KEYSPACE IF NOT EXISTS ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}"},
		{"CREATE KEYSPACE with trailing comma in replication map", "CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3,}"},
		{"CREATE KEYSPACE with comma-separated options", "CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3}, durable_writes = true"},
		{"DROP KEYSPACE", "DROP KEYSPACE ks"},
		{"DROP KEYSPACE IF EXISTS", "DROP KEYSPACE IF EXISTS ks"},
		{"BATCH", "BEGIN BATCH INSERT INTO users (id, name) VALUES (1, 'John'); UPDATE users SET name = 'Jane' WHERE id = 2; APPLY BATCH"},
		{"BATCH with USING", "BEGIN BATCH USING TIMESTAMP 1234567890 INSERT INTO users (id, name) VALUES (1, 'John'); APPLY BATCH"},
		{"UNLOGGED BATCH", "BEGIN UNLOGGED BATCH INSERT INTO users (id, name) VALUES (1, 'John'); APPLY BATCH"},
		{"LOGGED BATCH", "BEGIN LOGGED BATCH INSERT INTO users (id, name) VALUES (1, 'John'); APPLY BATCH"},
		{"TRUNCATE", "TRUNCATE users"},
		{"TRUNCATE TABLE", "TRUNCATE TABLE users"},
		{"system.local query", "SELECT * FROM system.local WHERE key = 'local'"},
		{"system.peers query", "SELECT * FROM system.peers"},
		{"system_schema.tables", "SELECT * FROM system_schema.tables WHERE keyspace_name = 'system'"},
		{"system_schema.columns", "SELECT * FROM system_schema.columns WHERE keyspace_name = 'system' AND table_name = 'local'"},
		{"virtual table", "SELECT * FROM vts.partition_key_statistics WHERE keyspace_name = 'test'"},
		{"aggregate functions", "SELECT count(*), sum(value), avg(value), min(value), max(value) FROM data"},
		{"window functions", "SELECT id, row_number() OVER (ORDER BY created_at) FROM events"},
		{"collection functions", "SELECT id, list, list[1], list[1:3] FROM data"},
		{"map functions", "SELECT id, profile, profile['email'] FROM users"},
		{"UDF calls", "SELECT my_function(id, name) FROM users"},
		{"UDA calls", "SELECT my_aggregate(value) FROM data"},
		{"token function in WHERE", "SELECT * FROM users WHERE token(id) > token(100)"},
		{"token with multiple args", "SELECT * FROM users WHERE token(id, name) > token(100, 'test')"},
		{"blob in WHERE", "SELECT * FROM data WHERE content = 0x48656c6c6f"},
		{"UUID in WHERE", "SELECT * FROM users WHERE id = 123e4567-e89b-12d3-a456-426614174000"},
		{"date in WHERE", "SELECT * FROM calendar WHERE date = '2023-01-01'"},
		{"time in WHERE", "SELECT * FROM schedule WHERE time = '12:30:00'"},
		{"timestamp in WHERE", "SELECT * FROM events WHERE created_at > '2023-01-01T00:00:00Z'"},
		{"inet in WHERE", "SELECT * FROM servers WHERE ip = '192.168.1.1'"},
		{"varint in WHERE", "SELECT * FROM bigints WHERE id = 12345678901234567890"},
		{"decimal in WHERE", "SELECT * FROM products WHERE price = 19.99"},
		{"scientific in WHERE", "SELECT * FROM data WHERE value = 1.5e10"},
		{"negative in WHERE", "SELECT * FROM users WHERE score = -100"},
		{"zero in WHERE", "SELECT * FROM users WHERE id = 0"},
		{"empty string in WHERE", "SELECT * FROM users WHERE name = ''"},
		{"NULL in WHERE", "SELECT * FROM users WHERE name = NULL"},
		{"boolean in WHERE", "SELECT * FROM users WHERE active = true"},
		{"list in WHERE", "SELECT * FROM users WHERE tags = ['a', 'b', 'c']"},
		{"set in WHERE", "SELECT * FROM users WHERE roles = {'admin', 'user'}"},
		{"map in WHERE", "SELECT * FROM users WHERE profile = {'email': 'test@example.com'}"},
		{"tuple in WHERE", "SELECT * FROM users WHERE coords = (1.5, 2.5)"},
		{"collection element access", "SELECT * FROM users WHERE tags[1] = 'important'"},
		{"map element access", "SELECT * FROM users WHERE profile['email'] = 'test@example.com'"},
		{"UDT field access", "SELECT * FROM users WHERE address.city = 'NYC'"},
		{"UDT nested field", "SELECT * FROM users WHERE address.location.lat = 40.7128"},
		{"collection in SELECT", "SELECT tags[1], profile['email'] FROM users"},
		{"UDT in SELECT", "SELECT address.city, address.zip FROM users"},
		{"tuple in SELECT", "SELECT coords FROM users"},
		{"function in SELECT", "SELECT to_unix_timestamp(created_at) FROM users"},
		{"cast in SELECT", "SELECT CAST(id AS TEXT) FROM users"},
		{"arithmetic in SELECT", "SELECT score + 10, price * 1.1 FROM data"},
		{"alias in SELECT", "SELECT id AS user_id, name AS user_name FROM users"},
		{"count distinct", "SELECT COUNT(DISTINCT name) FROM users"},
		{"max min", "SELECT MAX(score), MIN(score) FROM users"},
		{"sum avg", "SELECT SUM(value), AVG(value) FROM data"},
		{"nested expressions", "SELECT * FROM users WHERE (a = 1 AND b = 2) OR (c = 3 AND d = 4)"},
		{"multiple AND", "SELECT * FROM users WHERE a = 1 AND b = 2 AND c = 3 AND d = 4 AND e = 5"},
		{"multiple OR", "SELECT * FROM users WHERE a = 1 OR b = 2 OR c = 3 OR d = 4 OR e = 5"},
		{"mixed AND OR", "SELECT * FROM users WHERE (a = 1 OR b = 2) AND (c = 3 OR d = 4)"},
		{"NOT with AND", "SELECT * FROM users WHERE NOT (a = 1) AND NOT (b = 2)"},
		{"NOT with OR", "SELECT * FROM users WHERE NOT (a = 1) OR NOT (b = 2)"},
		{"parentheses priority", "SELECT * FROM users WHERE a = 1 AND (b = 2 OR c = 3)"},
		{"complex nested", "SELECT * FROM users WHERE ((a = 1 AND b = 2) OR (c = 3 AND d = 4)) AND (e = 5 OR f = 6)"},
		{"IN with expressions", "SELECT * FROM users WHERE id IN (1 + 1, 2 * 2, 3 - 1)"},
		{"BETWEEN with expressions", "SELECT * FROM users WHERE id BETWEEN 1 + 1 AND 10 - 2"},
		{"CONTAINS with expressions", "SELECT * FROM users WHERE tags CONTAINS 'prefix' || 'suffix'"},
		{"ORDER BY with expression", "SELECT * FROM users WHERE id = 1 ORDER BY name || age"},
		{"LIMIT with expression", "SELECT * FROM users LIMIT 10 + 5"},
		{"OFFSET with expression", "SELECT * FROM users LIMIT 10 OFFSET 5 * 2"},
		{"USING with expression", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 60 * 60"},
		{"UPDATE with expression", "UPDATE users SET score = score * 2 + 10 WHERE id = 1"},
		{"INSERT with expression", "INSERT INTO users (id, score) VALUES (1, 100 + 50 - 25)"},
		{"DELETE with expression", "DELETE FROM users WHERE id = 1 + 2"},
		{"CREATE with expression", "CREATE TABLE users (id UUID PRIMARY KEY, value INT) WITH default_time_to_live = 60 * 60"},
		{"qualified table in all statements", "SELECT * FROM ks.table; INSERT INTO ks.table VALUES (1); UPDATE ks.table SET x = 1; DELETE FROM ks.table WHERE id = 1; DROP TABLE ks.table"},
		{"case sensitivity in identifiers", "SELECT * FROM \"MyTable\" WHERE \"MyColumn\" = 'value'"},
		{"quoted identifiers", "SELECT * FROM \"table with spaces\" WHERE \"column with spaces\" = 'value'"},
		{"keywords as identifiers", "SELECT * FROM keyspace WHERE key = 'value'"},
		{"keywords as column names", "SELECT key, table, index FROM system.local"},
		{"keywords in qualified names", "SELECT ks.table.key FROM ks.table"},
		{"keywords in function names", "SELECT count(*), max(id), min(id) FROM users"},
		{"keywords in types", "CREATE TABLE users (id UUID PRIMARY KEY, text TEXT, int INT)"},
		{"keywords in options", "CREATE TABLE users (id UUID PRIMARY KEY) WITH compaction = {'class': 'LeveledCompactionStrategy'}"},
		{"keywords in operators", "SELECT * FROM users WHERE id IN (1, 2, 3)"},
		{"keywords in clauses", "SELECT * FROM users WHERE id = 1 ORDER BY name LIMIT 10"},
		{"keywords in modifiers", "SELECT DISTINCT name FROM users"},
		{"keywords in collection types", "CREATE TABLE users (id UUID PRIMARY KEY, list LIST<TEXT>, set SET<INT>, map MAP<TEXT, INT>)"},
		{"keywords in tuple types", "CREATE TABLE users (id UUID PRIMARY KEY, coords TUPLE<INT, INT>)"},
		{"keywords in frozen types", "CREATE TABLE users (id UUID PRIMARY KEY, data FROZEN<tuple<INT, TEXT>>)"},
		{"keywords in static columns", "CREATE TABLE users (id UUID, name TEXT, shared TEXT STATIC, PRIMARY KEY (id, name))"},
		{"keywords in clustering order", "CREATE TABLE users (id UUID, name TEXT, PRIMARY KEY (id, name)) WITH CLUSTERING ORDER BY (name DESC)"},
		{"keywords in allow filtering", "SELECT * FROM users WHERE name = 'John' ALLOW FILTERING"},
		{"keywords in using clause", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 3600"},
		{"keywords in if condition", "UPDATE users SET name = 'John' WHERE id = 1 IF EXISTS"},
		{"keywords in batch", "BEGIN BATCH INSERT INTO users (id, name) VALUES (1, 'John'); APPLY BATCH"},
		{"keywords in truncate", "TRUNCATE TABLE users"},
		{"keywords in alter", "ALTER TABLE users ADD email TEXT"},
		{"keywords in create index", "CREATE INDEX ON users (name)"},
		{"keywords in drop", "DROP TABLE users"},
		{"keywords in create keyspace", "CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in alter keyspace", "ALTER KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in drop keyspace", "DROP KEYSPACE ks"},
		{"keywords in system tables", "SELECT * FROM system.local WHERE key = 'local'"},
		{"keywords in system_schema", "SELECT * FROM system_schema.tables WHERE keyspace_name = 'system'"},
		{"keywords in vts", "SELECT * FROM vts.partition_key_statistics WHERE keyspace_name = 'test'"},
		{"keywords in aggregate functions", "SELECT count(*), sum(value), avg(value) FROM data"},
		{"keywords in collection functions", "SELECT list[1], list[1:3] FROM data"},
		{"keywords in map functions", "SELECT profile['email'] FROM users"},
		{"keywords in token function", "SELECT * FROM users WHERE token(id) > 0"},
		{"keywords in cast", "SELECT CAST(id AS TEXT) FROM users"},
		{"keywords in arithmetic", "SELECT score + 10, price * 1.1 FROM data"},
		{"keywords in alias", "SELECT id AS user_id FROM users"},
		{"keywords in distinct", "SELECT DISTINCT name FROM users"},
		{"keywords in count distinct", "SELECT COUNT(DISTINCT name) FROM users"},
		{"keywords in max min", "SELECT MAX(score), MIN(score) FROM users"},
		{"keywords in sum avg", "SELECT SUM(value), AVG(value) FROM data"},
		{"keywords in where", "SELECT * FROM users WHERE id = 1"},
		{"keywords in order by", "SELECT * FROM users ORDER BY name"},
		{"keywords in limit", "SELECT * FROM users LIMIT 10"},
		{"keywords in offset", "SELECT * FROM users LIMIT 10 OFFSET 5"},
		{"keywords in in", "SELECT * FROM users WHERE id IN (1, 2, 3)"},
		{"keywords in between", "SELECT * FROM users WHERE id BETWEEN 1 AND 10"},
		{"keywords in contains", "SELECT * FROM users WHERE tags CONTAINS 'important'"},
		{"keywords in allow filtering", "SELECT * FROM users WHERE name = 'John' ALLOW FILTERING"},
		{"keywords in using", "INSERT INTO users (id, name) VALUES (1, 'John') USING TTL 3600"},
		{"keywords in if", "UPDATE users SET name = 'John' WHERE id = 1 IF EXISTS"},
		{"keywords in batch", "BEGIN BATCH INSERT INTO users (id, name) VALUES (1, 'John'); APPLY BATCH"},
		{"keywords in truncate", "TRUNCATE TABLE users"},
		{"keywords in alter", "ALTER TABLE users ADD email TEXT"},
		{"keywords in create index", "CREATE INDEX ON users (name)"},
		{"keywords in drop", "DROP TABLE users"},
		{"keywords in create keyspace", "CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in alter keyspace", "ALTER KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in drop keyspace", "DROP KEYSPACE ks"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Parse error for '%s': %v", tt.input, err)
				return
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("✓ Parsed: %s", tt.input)
		})
	}
}

// ============================================
// Original Bug Fix Tests
// ============================================

func TestOriginalBugFixes(t *testing.T) {
	// Test the original bug that was reported
	tests := []struct {
		name  string
		input string
	}{
		{"original bug: key keyword", "SELECT * FROM system.local WHERE key='local'"},
		{"original bug: key with spaces", "SELECT * FROM system.local WHERE key = 'local'"},
		{"original bug: key with question mark", "SELECT * FROM system.local WHERE key = ?"},
		{"identifier with digit: table1", "SELECT * FROM table1"},
		{"identifier with digit: col2", "SELECT col2 FROM table1"},
		{"identifier with digit: whr", "SELECT * FROM table1 WHERE col2 = 3"},
		{"identifier starting with digit", "SELECT * FROM 1table WHERE 2col = 3"},
		{"mixed identifiers", "SELECT col1, col2, col3 FROM table1 WHERE col4 = 5"},
		{"qualified with digits", "SELECT keyspace1.table2.col3 FROM keyspace1.table2"},
		{"function with digits", "SELECT func1(col2) FROM table1"},
		{"keywords as identifiers", "SELECT * FROM ks WHERE key = 'value'"},
		{"keywords in WHERE", "SELECT * FROM users WHERE tbl = 'test'"},
		{"keywords in ORDER BY", "SELECT * FROM users ORDER BY key"},
		{"keywords in LIMIT", "SELECT * FROM users LIMIT 10"},
		{"keywords in CREATE", "CREATE TABLE ks (key TEXT PRIMARY KEY)"},
		{"keywords in INSERT", "INSERT INTO ks (key, tbl) VALUES ('k1', 't1')"},
		{"keywords in UPDATE", "UPDATE ks SET tbl = 't1' WHERE key = 'k1'"},
		{"keywords in DELETE", "DELETE FROM ks WHERE key = 'k1'"},
		{"keywords in DROP", "DROP TABLE ks"},
		{"keywords in ALTER", "ALTER TABLE ks ADD tbl TEXT"},
		{"keywords in CREATE INDEX", "CREATE INDEX ON ks (tbl)"},
		{"keywords in SELECT", "SELECT sel, frm, whr FROM ks"},
		{"keywords in function", "SELECT count(*), max(key) FROM ks"},
		{"keywords in collection", "SELECT list[1], set_col, map FROM ks"},
		{"keywords in type", "CREATE TABLE t (key TEXT PRIMARY KEY, tbl INT)"},
		{"keywords in options", "CREATE TABLE t (key TEXT PRIMARY KEY) WITH compaction = {'class': 'LeveledCompactionStrategy'}"},
		{"keywords in static", "CREATE TABLE t (key TEXT, tbl TEXT STATIC, PRIMARY KEY (key))"},
		{"keywords in clustering", "CREATE TABLE t (key TEXT, tbl TEXT, PRIMARY KEY (key, tbl))"},
		{"keywords in order", "CREATE TABLE t (key TEXT, tbl TEXT, PRIMARY KEY (key, tbl)) WITH CLUSTERING ORDER BY (tbl DESC)"},
		{"keywords in allow filtering", "SELECT * FROM t WHERE tbl = 'x' ALLOW FILTERING"},
		{"keywords in using", "INSERT INTO t (key, tbl) VALUES ('k', 't') USING TTL 3600"},
		{"keywords in if", "UPDATE t SET tbl = 't' WHERE key = 'k' IF EXISTS"},
		{"keywords in batch", "BEGIN BATCH INSERT INTO t (key, tbl) VALUES ('k', 't'); APPLY BATCH"},
		{"keywords in truncate", "TRUNCATE TABLE ks"},
		{"keywords in alter", "ALTER TABLE ks ADD tbl TEXT"},
		{"keywords in create index", "CREATE INDEX ON ks (tbl)"},
		{"keywords in drop", "DROP TABLE ks"},
		{"keywords in create ks", "CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in alter ks", "ALTER KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in drop ks", "DROP KEYSPACE ks"},
		{"keywords in system tables", "SELECT * FROM system.local WHERE key = 'local'"},
		{"keywords in system_schema", "SELECT * FROM system_schema.tables WHERE keyspace_name = 'ks'"},
		{"keywords in vts", "SELECT * FROM vts.partition_key_statistics WHERE keyspace_name = 'ks'"},
		{"keywords in aggregate", "SELECT count(*), sum(tbl), avg(key) FROM ks"},
		{"keywords in collection functions", "SELECT list[1], list[1:3] FROM ks"},
		{"keywords in map functions", "SELECT map['key'] FROM ks"},
		{"keywords in token", "SELECT * FROM ks WHERE token(key) > 0"},
		{"keywords in cast", "SELECT CAST(key AS TEXT) FROM ks"},
		{"keywords in arithmetic", "SELECT tbl + 10, key * 2 FROM ks"},
		{"keywords in alias", "SELECT key AS tbl FROM ks"},
		{"keywords in distinct", "SELECT DISTINCT tbl FROM ks"},
		{"keywords in count distinct", "SELECT COUNT(DISTINCT tbl) FROM ks"},
		{"keywords in max min", "SELECT MAX(key), MIN(tbl) FROM ks"},
		{"keywords in sum avg", "SELECT SUM(key), AVG(tbl) FROM ks"},
		{"keywords in whr", "SELECT * FROM ks WHERE key = 1"},
		{"keywords in order by", "SELECT * FROM ks ORDER BY tbl"},
		{"keywords in limit", "SELECT * FROM ks LIMIT 10"},
		{"keywords in offset", "SELECT * FROM ks LIMIT 10 OFFSET 5"},
		{"keywords in in", "SELECT * FROM ks WHERE key IN (1, 2, 3)"},
		{"keywords in between", "SELECT * FROM ks WHERE key BETWEEN 1 AND 10"},
		{"keywords in contains", "SELECT * FROM ks WHERE tbl CONTAINS 'x'"},
		{"keywords in allow filtering", "SELECT * FROM ks WHERE tbl = 'x' ALLOW FILTERING"},
		{"keywords in using", "INSERT INTO ks (key, tbl) VALUES ('k', 't') USING TTL 3600"},
		{"keywords in if", "UPDATE ks SET tbl = 't' WHERE key = 'k' IF EXISTS"},
		{"keywords in batch", "BEGIN BATCH INSERT INTO ks (key, tbl) VALUES ('k', 't'); APPLY BATCH"},
		{"keywords in truncate", "TRUNCATE TABLE ks"},
		{"keywords in alter", "ALTER TABLE ks ADD tbl TEXT"},
		{"keywords in create index", "CREATE INDEX ON ks (tbl)"},
		{"keywords in drop", "DROP TABLE ks"},
		{"keywords in create ks", "CREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in alter ks", "ALTER KEYSPACE ks WITH replication = {'class': 'SimpleStrategy'}"},
		{"keywords in drop ks", "DROP KEYSPACE ks"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Fatalf("Failed to parse '%s': %v", tt.input, err)
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("✓ Parsed: %s", tt.input)
		})
	}
}

// ============================================
// Performance Tests
// ============================================

func TestParserPerformance(t *testing.T) {
	// Test that the parser can handle common queries efficiently
	queries := []string{
		"SELECT * FROM users WHERE id = 1",
		"SELECT id, name, email FROM users WHERE id = 1 AND active = true",
		"SELECT * FROM users WHERE id IN (1, 2, 3, 4, 5) ORDER BY name LIMIT 10",
		"INSERT INTO users (id, name, email) VALUES (1, 'John', 'john@example.com')",
		"UPDATE users SET name = 'John', email = 'john@example.com' WHERE id = 1",
		"DELETE FROM users WHERE id = 1",
		"CREATE TABLE users (id UUID PRIMARY KEY, name TEXT, email TEXT)",
	}

	for _, query := range queries {
		p := NewParser(query)
		stmt, err := p.Parse()
		if err != nil {
			t.Errorf("Failed to parse: %s - %v", query, err)
		}
		if stmt == nil {
			t.Errorf("Parse returned nil for: %s", query)
		}
	}
}

// ============================================
// Error Handling Tests
// ============================================

func TestParserErrors(t *testing.T) {
	tests := []struct {
		name  string
		input string
	}{
		{"empty query", ""},
		{"invalid keyword", "INVALID * FROM users"},
		{"missing FROM", "SELECT *"},
		{"missing table", "SELECT * FROM"},
		{"unclosed string", "SELECT * FROM users WHERE name = 'John"},
		{"unclosed parentheses", "SELECT * FROM users WHERE (id = 1"},
		{"invalid operator", "SELECT * FROM users WHERE id === 1"},
		{"missing comma", "SELECT id name FROM users"},
		{"missing VALUES", "INSERT INTO users (id, name)"},
		{"missing WHERE", "UPDATE users SET name = 'John'"},
		{"missing SET", "UPDATE users name = 'John' WHERE id = 1"},
		{"missing primary key", "CREATE TABLE users (id UUID, name TEXT)"},
		{"invalid type", "CREATE TABLE users (id list<text PRIMARY KEY)"},
		{"missing semicolon in batch", "BEGIN BATCH INSERT INTO users (id) VALUES (1) APPLY BATCH"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			p := NewParser(tt.input)
			_, err := p.Parse()
			if err == nil {
				t.Errorf("Expected error for: %s", tt.input)
			} else {
				t.Logf("Got expected error for '%s': %v", tt.input, err)
			}
		})
	}
}

// ============================================
// Round-trip Tests
// ============================================

func TestRoundTrip(t *testing.T) {
	// Test that we can parse and the result has expected structure
	tests := []struct {
		input         string
		expectedTable string
	}{
		{"SELECT * FROM users", "users"},
		{"SELECT * FROM ks.users", "users"},
		{"INSERT INTO users (id, name) VALUES (1, 'John')", "users"},
		{"UPDATE users SET name = 'John' WHERE id = 1", "users"},
		{"DELETE FROM users WHERE id = 1", "users"},
		{"CREATE TABLE users (id UUID PRIMARY KEY)", "users"},
	}

	for _, tt := range tests {
		t.Run(tt.input, func(t *testing.T) {
			p := NewParser(tt.input)
			stmt, err := p.Parse()
			if err != nil {
				t.Logf("Parse error (may be expected): %v", err)
			}
			if stmt == nil {
				t.Fatalf("Parse returned nil for: %s", tt.input)
			}
			t.Logf("Successfully parsed: %s", tt.input)
		})
	}
}
