package executor

import (
	"context"
	"testing"

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

// TestVirtualTableIntegration tests the integration between executor and virtualtables
func TestVirtualTableIntegration(t *testing.T) {
	// Create a mock executor with virtual table support
	executor := &Executor{
		virtualExecutor: virtualtables.NewVirtualTableExecutor(virtualtables.NewRegistry()),
	}

	ctx := context.Background()

	// Test 1: Query system_views.clients through executor
	t.Run("clients_via_executor", func(t *testing.T) {
		cql := "SELECT * FROM system_views.clients"
		stmt, err := parser.NewParser(cql).Parse()
		if err != nil {
			t.Fatalf("Parse failed: %v", err)
		}

		selectStmt, ok := stmt.(*parser.SelectStatement)
		if !ok {
			t.Fatal("Expected SelectStatement")
		}

		// Check if it's detected as virtual table query
		if !virtualtables.IsVirtualTableQuery(selectStmt) {
			t.Fatal("Should be detected as virtual table query")
		}

		// Execute through virtual executor
		result, err := executor.virtualExecutor.Execute(ctx, selectStmt, "test_user")
		if err != nil {
			t.Fatalf("Execute failed: %v", err)
		}

		// Convert to executor.QueryResult
		converted := convertQueryResult(result)

		if len(converted.Columns) == 0 {
			t.Fatal("Expected columns")
		}

		t.Logf("Columns: %v", converted.Columns)
		t.Logf("Rows: %d", len(converted.Rows))
	})

	// Test 2: Query system_virtual_schema.tables
	t.Run("schema_via_executor", func(t *testing.T) {
		cql := "SELECT * FROM system_virtual_schema.tables"
		stmt, err := parser.NewParser(cql).Parse()
		if err != nil {
			t.Fatalf("Parse failed: %v", err)
		}

		selectStmt, ok := stmt.(*parser.SelectStatement)
		if !ok {
			t.Fatal("Expected SelectStatement")
		}

		if !virtualtables.IsVirtualTableQuery(selectStmt) {
			t.Fatal("Should be detected as virtual table query")
		}

		result, err := executor.virtualExecutor.Execute(ctx, selectStmt, "test_user")
		if err != nil {
			t.Fatalf("Execute failed: %v", err)
		}

		converted := convertQueryResult(result)

		if len(converted.Rows) == 0 {
			t.Fatal("Expected rows")
		}

		t.Logf("Schema tables: %d rows", len(converted.Rows))
	})

	// Test 3: Test convertQueryResult with nil
	t.Run("convert_nil", func(t *testing.T) {
		result := convertQueryResult(nil)
		if result == nil {
			t.Fatal("Expected non-nil result")
		}
		if result.Columns == nil {
			t.Error("Expected non-nil columns")
		}
		if result.Rows == nil {
			t.Error("Expected non-nil rows")
		}
	})
}

// TestExecuteVirtualTableQuery tests the full Execute flow with virtual tables
func TestExecuteVirtualTableQuery(t *testing.T) {
	// This test verifies that the Execute method correctly routes virtual table queries
	// Note: We can't fully test this without a real poolManager, but we can verify
	// the routing logic works

	// Create a minimal executor
	executor := &Executor{
		virtualExecutor: virtualtables.NewVirtualTableExecutor(virtualtables.NewRegistry()),
	}

	ctx := context.Background()

	// Test that virtual table queries are detected
	cql := "SELECT * FROM system_views.clients"
	stmt, err := parser.NewParser(cql).Parse()
	if err != nil {
		t.Fatalf("Parse failed: %v", err)
	}

	selectStmt, ok := stmt.(*parser.SelectStatement)
	if !ok {
		t.Fatal("Expected SelectStatement")
	}

	// Verify detection
	if !virtualtables.IsVirtualTableQuery(selectStmt) {
		t.Fatal("Should detect virtual table query")
	}

	// Execute and verify result
	result, err := executor.virtualExecutor.Execute(ctx, selectStmt, "test_user")
	if err != nil {
		t.Fatalf("Execute failed: %v", err)
	}

	converted := convertQueryResult(result)
	if converted == nil {
		t.Fatal("Expected non-nil result")
	}

	t.Logf("Successfully executed virtual table query: %d rows", len(converted.Rows))
}
