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

// builtin-os-file.go
package expr

import (
	"fmt"
	"slices"

	"git.portale-stac.it/go-pkg/expr/file"
	"git.portale-stac.it/go-pkg/expr/kern"
)

const paramHandleOrPath = "handle-or-path"

type fileIterBase struct {
	reader    *file.Reader
	index     int64
	count     int64
	autoClose bool
}

func (it *fileIterBase) Count() int64 {
	return it.count
}

func (it *fileIterBase) Index() int64 {
	return it.index
}

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

func (it *fileIterBase) reset() {
	it.index = -1
	it.count = 0
}

func (it *fileIterBase) increment() {
	it.index++
	it.count++
}

func (it *fileIterBase) repr(typeName string) string {
	if it.reader.Valid() {
		return fmt.Sprintf("$(%s@%q)", typeName, it.reader.GetName())
	}
	return fmt.Sprintf("$(%s@<nil>)", typeName)
}

func initFileHandle(ctx kern.ExprContext, name string, args map[string]any) (handle *file.Reader, invalidFileHandle any, autoClose bool, err error) {
	var ok bool

	if handle, ok = args[paramHandleOrPath].(*file.Reader); !ok {
		if fileName, ok := args[paramHandleOrPath].(string); ok && len(fileName) > 0 {
			var handleAny any
			if handleAny, err = openFileFunc(ctx, name, map[string]any{kern.ParamFilepath: fileName}); err != nil {
				return
			}
			if handleAny != nil {
				handle = handleAny.(*file.Reader)
				autoClose = true
			}
		} else {
			invalidFileHandle = args[paramHandleOrPath]
		}
	}
	return
}
