package executor

import (
	"testing"

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

func TestApplyCastConversionsForDMLBindMarker(t *testing.T) {
	stmt := mustParseStatement(t, "INSERT INTO ks.tbl (v) VALUES (CAST(? AS text))")
	insertStmt, ok := stmt.(*parser.InsertStatement)
	if !ok {
		t.Fatalf("expected insert statement, got %T", stmt)
	}
	params := []interface{}{int32(7)}
	updated, updatedParams, changed, err := applyCastConversionsForDML(insertStmt, params, nil)
	if err != nil {
		t.Fatalf("applyCastConversionsForDML failed: %v", err)
	}
	if changed {
		t.Fatalf("expected no statement rewrite for bind marker cast")
	}
	updatedInsert, ok := updated.(*parser.InsertStatement)
	if !ok {
		t.Fatalf("expected insert statement, got %T", updated)
	}
	if _, ok := updatedInsert.Values[0][0].(*parser.CastExpr); !ok {
		t.Fatalf("expected CAST expression to remain, got %T", updatedInsert.Values[0][0])
	}
	if updatedParams[0] != "7" {
		t.Fatalf("expected converted param \"7\", got %#v", updatedParams[0])
	}
}

func TestApplyCastConversionsForDMLLiteral(t *testing.T) {
	stmt := mustParseStatement(t, "UPDATE ks.tbl SET v = CAST('42' AS int) WHERE id = 1")
	updateStmt, ok := stmt.(*parser.UpdateStatement)
	if !ok {
		t.Fatalf("expected update statement, got %T", stmt)
	}
	updated, _, changed, err := applyCastConversionsForDML(updateStmt, nil, nil)
	if err != nil {
		t.Fatalf("applyCastConversionsForDML failed: %v", err)
	}
	if !changed {
		t.Fatalf("expected statement rewrite for literal cast")
	}
	updatedUpdate, ok := updated.(*parser.UpdateStatement)
	if !ok {
		t.Fatalf("expected update statement, got %T", updated)
	}
	assign := updatedUpdate.Assigments[0]
	lit, ok := assign.Value.(*parser.IntegerLiteral)
	if !ok {
		t.Fatalf("expected integer literal, got %T", assign.Value)
	}
	if lit.Value != 42 {
		t.Fatalf("expected literal 42, got %d", lit.Value)
	}
}
