package photoshop

import (
	"bytes"
	"encoding/binary"
)

var (
	ps3Header      = []byte("Photoshop 3.0\x00")
	ps3BlockHeader = []byte("8BIM")
)

const (
	IptcKey       = "\x04\x04"
	ResolutionKey = "\x03\xed"
)

type PhotoshopMap map[string][]byte

func Parse(data []byte, m PhotoshopMap) {
	buf := bytes.NewBuffer(data)

	if !bytes.Equal(buf.Next(14), ps3Header) {
		return
	}

	// Read blocks
	// Minimal block size is 12 (4 blockHeader + 2 resoureceID + 2 name + 4 blockSize)
	for buf.Len() >= 12 {
		if !bytes.Equal(buf.Bytes()[:4], ps3BlockHeader) {
			buf.Next(1)
			continue
		}

		// Skip block header
		buf.Next(4)

		resoureceID := buf.Next(2)

		// Skip name
		// Name is zero terminated string padded to even
		for buf.Len() > 0 && buf.Next(2)[1] != 0 {
		}

		if buf.Len() < 4 {
			break
		}

		blockSize := int(binary.BigEndian.Uint32(buf.Next(4)))

		if buf.Len() < blockSize {
			break
		}
		blockData := buf.Next(blockSize)

		m[string(resoureceID)] = blockData
	}
}

func (m PhotoshopMap) Dump() []byte {
	buf := new(bytes.Buffer)
	buf.Grow(26)

	buf.Write(ps3Header)

	for id, data := range m {
		if len(data) == 0 {
			continue
		}

		buf.Write(ps3BlockHeader)
		buf.WriteString(id)
		// Write empty name
		buf.Write([]byte{0, 0})
		binary.Write(buf, binary.BigEndian, uint32(len(data))) //nolint:gosec
		buf.Write(data)
	}

	return buf.Bytes()
}
