package compiler

import "fmt"

// ForLoopInfo stores information about a FOR loop
type ForLoopInfo struct {
	VarName     string
	VarKind     VarKind
	EndOperand  *OperandInfo
	LoopLabel   string
	SkipLabel   string
	UseLongJump bool
}

// OperandInfo describes an operand (variable or literal)
type OperandInfo struct {
	VarName string
	VarKind VarKind
	Value   uint16
	IsVar   bool
}

// ForStack manages the stack of FOR loop contexts
type ForStack struct {
	stack []*ForLoopInfo
}

// NewForStack creates a new ForStack
func NewForStack() *ForStack {
	return &ForStack{
		stack: make([]*ForLoopInfo, 0),
	}
}

// Push adds a new FOR loop context to the stack
func (fs *ForStack) Push(info *ForLoopInfo) {
	fs.stack = append(fs.stack, info)
}

// Peek returns the top FOR loop context without removing it
func (fs *ForStack) Peek() (*ForLoopInfo, error) {
	if len(fs.stack) == 0 {
		return nil, fmt.Errorf("stack underflow: FOR stack is empty")
	}
	return fs.stack[len(fs.stack)-1], nil
}

// Pop removes and returns the top FOR loop context
func (fs *ForStack) Pop() (*ForLoopInfo, error) {
	if len(fs.stack) == 0 {
		return nil, fmt.Errorf("stack underflow: FOR stack is empty")
	}
	info := fs.stack[len(fs.stack)-1]
	fs.stack = fs.stack[:len(fs.stack)-1]
	return info, nil
}

// IsEmpty returns true if the stack is empty
func (fs *ForStack) IsEmpty() bool {
	return len(fs.stack) == 0
}

// Size returns the number of items on the stack
func (fs *ForStack) Size() int {
	return len(fs.stack)
}
