package xmlparser

import (
	"encoding/xml"
	"io"
)

// Parsable defines the interface that models must implement to be parseable
type Parsable interface {
	// Validate validates the parsed model
	Validate() error
	// GetID returns a unique identifier for the model
	GetID() string
}

// Parser defines the generic XML parser interface
type Parser[T Parsable] interface {
	// Parse parses XML from reader into the target type
	Parse(reader io.Reader) (*T, error)
	// ParseString parses XML from string into the target type
	ParseString(xmlData string) (*T, error)
	// ParseBytes parses XML from byte slice into the target type
	ParseBytes(xmlData []byte) (*T, error)
	// Validate validates XML against schema (if supported)
	Validate(reader io.Reader) error
}

// XMLMetadata contains metadata about the parsed XML
type XMLMetadata struct {
	XMLName   xml.Name `xml:""`
	Namespace string   `json:"namespace,omitempty"`
	Version   string   `json:"version,omitempty"`
	Encoding  string   `json:"encoding,omitempty"`
}

// ParseResult contains the result of XML parsing
type ParseResult[T Parsable] struct {
	Data     *T           `json:"data"`
	Metadata *XMLMetadata `json:"metadata,omitempty"`
	Errors   []string     `json:"errors,omitempty"`
	Warnings []string     `json:"warnings,omitempty"`
}

// ParserOptions configures the parser behavior
type ParserOptions struct {
	// StrictValidation enables strict XML validation
	StrictValidation bool
	// AllowEmptyElements allows empty XML elements
	AllowEmptyElements bool
	// PreserveWhitespace preserves whitespace in text elements
	PreserveWhitespace bool
	// IgnoreUnknownElements ignores unknown XML elements
	IgnoreUnknownElements bool
	// MaxDepth maximum nesting depth allowed
	MaxDepth int
	// MaxSize maximum XML size in bytes
	MaxSize int64
}

// DefaultParserOptions returns default parser options
func DefaultParserOptions() *ParserOptions {
	return &ParserOptions{
		StrictValidation:      true,
		AllowEmptyElements:    true,
		PreserveWhitespace:    false,
		IgnoreUnknownElements: false,
		MaxDepth:              100,
		MaxSize:               10 * 1024 * 1024, // 10MB
	}
}
