package imagemeta

import (
	"encoding/xml"
	"errors"
	"fmt"
	"io"
)

var xmpSkipNamespaces = map[string]bool{
	"xmlns": true,
	"http://www.w3.org/1999/02/22-rdf-syntax-ns#": true,
	"http://purl.org/dc/elements/1.1/":            true,
}

type rdf struct {
	Description rdfDescription `xml:"Description"`
}

type rdfDescription struct {
	Attrs []xml.Attr `xml:",any,attr"`
}

type xmpmeta struct {
	RDF rdf `xml:"RDF"`
}

func decodeXMP(r io.Reader, opts Options) error {
	if opts.HandleXMP != nil {
		if err := opts.HandleXMP(r); err != nil {
			return err
		}
		// Read one more byte to make sure we're at EOF.
		var b [1]byte
		if _, err := r.Read(b[:]); err != io.EOF {
			return errors.New("expected EOF after XMP")
		}
		return nil
	}

	var meta xmpmeta
	if err := xml.NewDecoder(r).Decode(&meta); err != nil {
		return newInvalidFormatError(fmt.Errorf("decoding XMP: %w", err))
	}

	for _, attr := range meta.RDF.Description.Attrs {
		if xmpSkipNamespaces[attr.Name.Space] {
			continue
		}

		tagInfo := TagInfo{
			Source:    XMP,
			Tag:       attr.Name.Local,
			Namespace: attr.Name.Space,
			Value:     attr.Value,
		}

		if !opts.ShouldHandleTag(tagInfo) {
			continue
		}

		if err := opts.HandleTag(tagInfo); err != nil {
			return err
		}
	}
	return nil
}
