// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.

// t_iter-list_test.go
package expr

import (
	"io"
	"testing"

	"git.portale-stac.it/go-pkg/expr/types/array"
)

func TestNewListIterator(t *testing.T) {
	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{1, 3, 1})
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "b" {
		t.Errorf("expected %q, got %q", "b", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewListIterator2(t *testing.T) {
	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{3, 1, -1})
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "d" {
		t.Errorf("expected %q, got %q", "d", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewListIterator3(t *testing.T) {
	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{1, -1, 1})
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "b" {
		t.Errorf("expected %q, got %q", "b", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList2(t *testing.T) {
	list := []any{"a", "b", "c", "d"}
	it := NewArrayIterator(list)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "a" {
		t.Errorf("expected %q, got %q", "a", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList3(t *testing.T) {
	list := []any{"a", "b", "c", "d"}
	it, _ := NewIterator(nil, list, nil)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "a" {
		t.Errorf("expected %q, got %q", "a", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList4(t *testing.T) {
	list := any(nil)
	it, _ := NewIterator(nil, list, nil)
	if _, err := it.Next(); err != io.EOF {
		t.Errorf("error: %v", err)
	}
}

func TestNewIterList5(t *testing.T) {
	list := "123"
	it, _ := NewIterator(nil, list, nil)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "123" {
		t.Errorf("expected %q, got %q", "123", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewIterList6(t *testing.T) {
	ctx := NewSimpleStore()
	a := array.NewArrayA("a", "b", "c", "d")
	it1, _ := NewIterator(ctx, a, nil)
	it, _ := NewIterator(ctx, it1, nil)
	if item, err := it.Next(); err != nil {
		t.Errorf("error: %v", err)
	} else if item != "a" {
		t.Errorf("expected %q, got %q", "a", item)
	} else {
		t.Logf("Next: %v", item)
	}
}

func TestNewString(t *testing.T) {
	list := "123"
	it, _ := NewIterator(nil, list, nil)
	if s := it.String(); s != "$([#1])" {
		t.Errorf("expected $([#1]), got %s", s)
	}
}

func TestHasOperation(t *testing.T) {

	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{1, 3, 1})
	hasOp := it.HasOperation("reset")
	if !hasOp {
		t.Errorf("HasOperation(reset) must be true, got false")
	}
}

func TestCallOperationReset(t *testing.T) {

	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{1, 3, 1})
	if v, err := it.CallOperation("reset", nil); err != nil {
		t.Errorf("Error on CallOperation(reset): %v", err)
	} else {
		t.Logf("Reset result: %v", v)
	}
}

func TestCallOperationIndex(t *testing.T) {

	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{1, 3, 1})
	if v, err := it.CallOperation("index", nil); err != nil {
		t.Errorf("Error on CallOperation(index): %v", err)
	} else {
		t.Logf("Index result: %v", v)
	}
}

func TestCallOperationCount(t *testing.T) {

	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{1, 3, 1})
	if v, err := it.CallOperation("count", nil); err != nil {
		t.Errorf("Error on CallOperation(count): %v", err)
	} else {
		t.Logf("Count result: %v", v)
	}
}

func TestCallOperationUnknown(t *testing.T) {

	a := array.NewArrayA("a", "b", "c", "d")
	it := NewArrayIteratorFromArray(a, []any{1, 3, 1})
	if v, err := it.CallOperation("unknown", nil); err == nil {
		t.Errorf("Expected error on CallOperation(unknown), got %v", v)
	}
}
