package executor

import (
	"bytes"
	"encoding/binary"
	"testing"

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

func TestRowsResultGlobalSpecAuto(t *testing.T) {
	translator := NewQueryResultTranslator()
	result := &QueryResult{
		Columns: []ColumnInfo{
			{Keyspace: "ks", Table: "tbl", Name: "id", Type: "int"},
			{Keyspace: "ks", Table: "tbl", Name: "name", Type: "text"},
		},
		Rows: []Row{
			{Values: []interface{}{int32(1), "alpha"}},
		},
	}

	frame, err := translator.TranslateToResultFrame(result, 0)
	if err != nil {
		t.Fatalf("TranslateToResultFrame failed: %v", err)
	}

	body := frame.Body
	pos := 4 // result kind
	flags := binary.BigEndian.Uint32(body[pos : pos+4])
	if flags&resultMetadataGlobalSpec == 0 {
		t.Fatalf("expected GLOBAL_TABLES_SPEC flag set")
	}
}

func TestPreparedMetadataIDV5(t *testing.T) {
	columns := []ColumnInfo{
		{Keyspace: "ks", Table: "tbl", Name: "id", Type: "int"},
		{Keyspace: "ks", Table: "tbl", Name: "name", Type: "text"},
	}
	prepared := &PreparedStatement{
		ID:         "prepared-id",
		Columns:    columns,
		MetadataID: computeResultMetadataID(columns),
	}

	translator := NewQueryResultTranslator()
	body := translator.BuildPreparedResult(prepared, 5)

	pos := 0
	_ = binary.BigEndian.Uint32(body[pos : pos+4])
	pos += 4

	idLen := int(binary.BigEndian.Uint16(body[pos : pos+2]))
	pos += 2 + idLen

	metadataLen := int(binary.BigEndian.Uint16(body[pos : pos+2]))
	pos += 2
	if metadataLen == 0 {
		t.Fatalf("expected non-empty metadata ID")
	}
	metadata := body[pos : pos+metadataLen]
	if !bytes.Equal(metadata, prepared.MetadataID) {
		t.Fatalf("metadata ID mismatch")
	}
}

func TestMetadataIDIncludesTypeInfo(t *testing.T) {
	base := ColumnInfo{Keyspace: "ks", Table: "tbl", Name: "vec", Type: "vector<float, 2>"}
	colsA := []ColumnInfo{
		{
			Keyspace: base.Keyspace,
			Table:    base.Table,
			Name:     base.Name,
			Type:     base.Type,
			TypeInfo: &types.VectorTypeInfo{ElemType: "float", Size: 2},
		},
	}
	colsB := []ColumnInfo{
		{
			Keyspace: base.Keyspace,
			Table:    base.Table,
			Name:     base.Name,
			Type:     base.Type,
			TypeInfo: &types.VectorTypeInfo{ElemType: "float", Size: 3},
		},
	}

	idA := computeResultMetadataID(colsA)
	idB := computeResultMetadataID(colsB)
	if bytes.Equal(idA, idB) {
		t.Fatalf("expected metadata IDs to differ for vector size change")
	}
	if !bytes.Equal(idA, computeResultMetadataID(colsA)) {
		t.Fatalf("metadata ID should be stable for identical inputs")
	}
}
