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

// iter-list.go
package expr

import "io"

type ListIterator struct {
	a     *ListType
	index int
}

func NewListIterator(list *ListType) *ListIterator {
	return &ListIterator{a: list, index: 0}
}

func NewArrayIterator(array []any) *ListIterator {
	return &ListIterator{a: (*ListType)(&array), index: 0}
}

func NewAnyIterator(value any) (it *ListIterator) {
	if value == nil {
		it = NewArrayIterator([]any{})
	} else if list, ok := value.(*ListType); ok {
		it = NewListIterator(list)
	} else if array, ok := value.([]any); ok {
		it = NewArrayIterator(array)
	} else if it1, ok := value.(*ListIterator); ok {
		it = it1
	} else {
		it = NewArrayIterator([]any{value})
	}
	return
}

func (it *ListIterator) HasOperation(name string) bool {
	return false
}

func (it *ListIterator) CallOperation(name string, args []any) (any, error) {
	return nil, errNoOperation(name)
}

func (it *ListIterator) Current() (item any, err error) {
	a := *(it.a)
	if it.index >= 0 && it.index < len(a) {
		item = a[it.index]
	} else {
		err = io.EOF
	}
	return
}

func (it *ListIterator) Next() (item any, err error) {
	if item, err = it.Current(); err != io.EOF {
		it.index++
	}
	// if it.index < len(it.a) {
	// 	item = it.a[it.index]
	// 	it.index++
	// } else {
	// 	err = io.EOF
	// }
	return
}

func (it *ListIterator) Index() int {
	return it.index - 1
}