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

// iter-factory.go
package expr

import (
	"slices"

	"git.portale-stac.it/go-pkg/expr/kern"
	"git.portale-stac.it/go-pkg/expr/scan"
	"git.portale-stac.it/go-pkg/expr/types/array"
	"git.portale-stac.it/go-pkg/expr/types/dict"
	"git.portale-stac.it/go-pkg/expr/types/list"
)

func NewFormalIterator(value any) (it kern.Iterator) {
	if value == nil {
		it = NewArrayIterator([]any{})
	} else {
		it = NewArrayIterator([]any{value})
	}
	return
}

func NewIterator(ctx kern.ExprContext, value any, ops []*scan.Term) (it kern.Iterator, err error) {
	if value == nil {
		return NewArrayIterator([]any{}), nil
	}

	switch v := value.(type) {
	case *array.ArrayType:
		it = NewArrayIteratorFromArray(v, nil)
	case *list.LinkedList:
		it = NewLinkedListIterator(v, nil)
	case *dict.DictType:
		it, err = NewDictIterator(v, nil)
	case []any:
		it = NewArrayIterator(v)
	case kern.Iterator:
		// var exprs []*scan.Term
		it, err = NewIterIter(v, ctx, ops)
	default:
		it = NewArrayIterator([]any{value})
	}
	return
}

func HasIterStandardOperations(name string) bool {
	return slices.Contains([]string{kern.NextName, kern.ResetName, kern.IndexName, kern.CountName, kern.CurrentName, kern.CleanName}, name)
}

// func HasIterOperations(name string, ops ...string) bool {
// 	return slices.Contains([]string{
// 		kern.NextName, kern.ResetName, kern.IndexName, kern.CountName, kern.CurrentName, kern.CleanName,
// 	}, name) ||
// 		slices.Contains(ops, name)
// }
