//go:build integration
// +build integration

package integration_test

import (
	"fmt"
	"testing"

	"github.com/apache/cassandra-gocql-driver/v2"
	"github.com/everything-on-mysql/cassandra-on-mysql/pkg/cql"
)

func TestUnsupportedCollectionOpsInvalid(t *testing.T) {
	session := newSession(t, sessionOptions{disableHostLookup: true})

	keyspace := uniqueKeyspace()
	if err := session.Query(createKeyspaceCQL(keyspace)).Exec(); err != nil {
		t.Fatalf("create keyspace failed: %v", err)
	}
	t.Cleanup(func() {
		_ = session.Query(dropKeyspaceCQL(keyspace)).Exec()
	})

	table := "collection_ops"
	create := fmt.Sprintf("CREATE TABLE %s.%s (id int PRIMARY KEY, tags list<text>, attrs map<text, text>)", keyspace, table)
	if err := session.Query(create).Exec(); err != nil {
		t.Fatalf("create table failed: %v", err)
	}

	queries := []string{
		fmt.Sprintf("UPDATE %s.%s SET tags[1:2] = ['b'] WHERE id = 1", keyspace, table),
		fmt.Sprintf("UPDATE %s.%s SET attrs = attrs - {'k2': 'v2'} WHERE id = 1", keyspace, table),
	}

	for _, query := range queries {
		t.Run(query, func(t *testing.T) {
			err := session.Query(query).Exec()
			requireErrorCode(t, err, cql.ErrorCodeInvalid)
		})
	}
}

func TestUnsupportedCounterUpdateInvalid(t *testing.T) {
	session := newSession(t, sessionOptions{disableHostLookup: true})

	keyspace := uniqueKeyspace()
	if err := session.Query(createKeyspaceCQL(keyspace)).Exec(); err != nil {
		t.Fatalf("create keyspace failed: %v", err)
	}
	t.Cleanup(func() {
		_ = session.Query(dropKeyspaceCQL(keyspace)).Exec()
	})

	table := "counter_ops"
	create := fmt.Sprintf("CREATE TABLE %s.%s (id int PRIMARY KEY, cnt counter)", keyspace, table)
	if err := session.Query(create).Exec(); err != nil {
		t.Fatalf("create table failed: %v", err)
	}

	query := fmt.Sprintf("UPDATE %s.%s SET cnt = 1 WHERE id = 1", keyspace, table)
	err := session.Query(query).Exec()
	requireErrorCode(t, err, cql.ErrorCodeInvalid)
}

func TestUnsetValuesSkipped(t *testing.T) {
	session := newSession(t, sessionOptions{disableHostLookup: true})

	keyspace := uniqueKeyspace()
	if err := session.Query(createKeyspaceCQL(keyspace)).Exec(); err != nil {
		t.Fatalf("create keyspace failed: %v", err)
	}
	t.Cleanup(func() {
		_ = session.Query(dropKeyspaceCQL(keyspace)).Exec()
	})

	table := "unset_values"
	if err := session.Query(createTableCQL(keyspace, table)).Exec(); err != nil {
		t.Fatalf("create table failed: %v", err)
	}

	insert := fmt.Sprintf("INSERT INTO %s.%s (id, name, idx) VALUES (?, ?, ?)", keyspace, table)
	if err := session.Query(insert, 1, "alpha", 1).Exec(); err != nil {
		t.Fatalf("insert failed: %v", err)
	}

	update := fmt.Sprintf("UPDATE %s.%s SET name = ?, idx = ? WHERE id = ?", keyspace, table)
	if err := session.Query(update, gocql.UnsetValue, 2, 1).Exec(); err != nil {
		t.Fatalf("update failed: %v", err)
	}

	var name []byte
	var idx int
	if err := session.Query(fmt.Sprintf("SELECT name, idx FROM %s.%s WHERE id = 1", keyspace, table)).Scan(&name, &idx); err != nil {
		t.Fatalf("select failed: %v", err)
	}
	if string(name) != "alpha" {
		t.Fatalf("expected name to remain 'alpha' due to UNSET, got %v", name)
	}
	if idx != 2 {
		t.Fatalf("unexpected idx after update: %v", idx)
	}
}
