package executor

import (
	"testing"

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

func newEligibilityExecutor() *Executor {
	return &Executor{
		poolManager: &mysqlbackend.PoolManager{},
		preparedCache: preparedCacheConfig{
			enabled: true,
		},
	}
}

func parseStmt(t *testing.T, cql string) parser.Statement {
	t.Helper()
	stmt, err := parser.NewParser(cql).Parse()
	if err != nil {
		t.Fatalf("parse failed for %q: %v", cql, err)
	}
	return stmt
}

func TestPreparedCacheEligibilitySelectPaging(t *testing.T) {
	exec := newEligibilityExecutor()
	prepared := &PreparedStatement{}
	stmt := parseStmt(t, "SELECT * FROM ks.tbl WHERE id = ?")

	if !exec.preparedCacheEligible(prepared, stmt, nil) {
		t.Fatalf("expected select to be eligible without paging")
	}
	if exec.preparedCacheEligible(prepared, stmt, &PagingOptions{PageSize: 10}) {
		t.Fatalf("expected select with paging to be ineligible")
	}
}

func TestPreparedCacheEligibilityInsertJSON(t *testing.T) {
	exec := newEligibilityExecutor()
	prepared := &PreparedStatement{}
	stmt := parseStmt(t, "INSERT INTO ks.tbl JSON '{\"id\": 1}'")

	if exec.preparedCacheEligible(prepared, stmt, nil) {
		t.Fatalf("expected JSON insert to be ineligible")
	}
}

func TestPreparedCacheEligibilityUpdateMutation(t *testing.T) {
	exec := newEligibilityExecutor()
	prepared := &PreparedStatement{}
	stmt := parseStmt(t, "UPDATE ks.tbl SET value = value + ? WHERE id = ?")

	if exec.preparedCacheEligible(prepared, stmt, nil) {
		t.Fatalf("expected update with column reference to be ineligible")
	}
}

func TestPreparedCacheEligibilityDeleteAssignments(t *testing.T) {
	exec := newEligibilityExecutor()
	prepared := &PreparedStatement{}
	stmt := parseStmt(t, "DELETE value FROM ks.tbl WHERE id = ?")

	if exec.preparedCacheEligible(prepared, stmt, nil) {
		t.Fatalf("expected delete with assignments to be ineligible")
	}
}
