//go:build !yq_noini

package yqlib

import (
	"fmt"
	"io"

	"github.com/go-ini/ini"
)

type iniDecoder struct {
	reader   io.Reader
	finished bool // Flag to signal completion of processing
	prefs    INIPreferences
}

func NewINIDecoder(prefs INIPreferences) Decoder {
	return &iniDecoder{
		finished: false, // Initialise the flag as false
		prefs:    prefs,
	}
}

func (dec *iniDecoder) Init(reader io.Reader) error {
	// Store the reader for use in Decode
	dec.reader = reader
	dec.finished = false
	return nil
}

func (dec *iniDecoder) Decode() (*CandidateNode, error) {
	// If processing is already finished, return io.EOF
	if dec.finished {
		return nil, io.EOF
	}

	// Read all content from the stored reader
	content, err := io.ReadAll(dec.reader)
	if err != nil {
		return nil, fmt.Errorf("failed to read INI content: %w", err)
	}

	// Parse the INI content
	loadOpts := ini.LoadOptions{
		PreserveSurroundedQuote: dec.prefs.PreserveSurroundedQuote,
	}
	cfg, err := ini.LoadSources(loadOpts, content)
	if err != nil {
		return nil, fmt.Errorf("failed to parse INI content: %w", err)
	}

	// Create a root CandidateNode as a MappingNode (since INI is key-value based)
	root := &CandidateNode{
		Kind:  MappingNode,
		Tag:   "!!map",
		Value: "",
	}

	// Process each section in the INI file
	for _, section := range cfg.Sections() {
		sectionName := section.Name()

		if sectionName == ini.DefaultSection {
			// For the default section, add key-value pairs directly to the root node
			for _, key := range section.Keys() {
				keyName := key.Name()
				keyValue := key.String()

				// Create a key node (scalar for the key name)
				keyNode := createStringScalarNode(keyName)
				// Create a value node (scalar for the value)
				valueNode := createStringScalarNode(keyValue)

				// Add key-value pair to the root node
				root.AddKeyValueChild(keyNode, valueNode)
			}
		} else {
			// For named sections, create a nested map
			sectionNode := &CandidateNode{
				Kind:  MappingNode,
				Tag:   "!!map",
				Value: "",
			}

			// Add key-value pairs to the section node
			for _, key := range section.Keys() {
				keyName := key.Name()
				keyValue := key.String()

				// Create a key node (scalar for the key name)
				keyNode := createStringScalarNode(keyName)
				// Create a value node (scalar for the value)
				valueNode := createStringScalarNode(keyValue)

				// Add key-value pair to the section node
				sectionNode.AddKeyValueChild(keyNode, valueNode)
			}

			// Create a key node for the section name
			sectionKeyNode := createStringScalarNode(sectionName)
			// Add the section as a nested map to the root node
			root.AddKeyValueChild(sectionKeyNode, sectionNode)
		}
	}

	// Set the finished flag to true to prevent further Decode calls
	dec.finished = true

	// Return the root node
	return root, nil
}
