package qmc

import (
	"encoding/binary"
	"fmt"
	"io"
)

type qqMusicTagMusicEx struct {
	songid        uint32 // Song ID
	unknown_1     uint32 // unused & unknown
	unknown_2     uint32 // unused & unknown
	mid           string // Media ID
	mediafile     string // real file name
	unknown_3     uint32 // unused; uninitialized memory?
	sizeof_struct uint32 // 19.57: fixed value: 0xC0
	version       uint32 // 19.57: fixed value: 0x01
	tag_magic     []byte // fixed value "musicex\0" (8 bytes)
}

func (tag *qqMusicTagMusicEx) Read(raw io.ReadSeeker) (int64, error) {
	_, err := raw.Seek(-16, io.SeekEnd)
	if err != nil {
		return 0, fmt.Errorf("musicex seek error: %w", err)
	}

	footerBuf := make([]byte, 4)
	footerBuf, err = io.ReadAll(io.LimitReader(raw, 4))
	if err != nil {
		return 0, fmt.Errorf("get musicex error: %w", err)
	}
	footerLen := int64(binary.LittleEndian.Uint32(footerBuf))

	audioLen, err := raw.Seek(-footerLen, io.SeekEnd)
	buf, err := io.ReadAll(io.LimitReader(raw, audioLen))
	if err != nil {
		return 0, err
	}

	tag.songid = binary.LittleEndian.Uint32(buf[0:4])
	tag.unknown_1 = binary.LittleEndian.Uint32(buf[4:8])
	tag.unknown_2 = binary.LittleEndian.Uint32(buf[8:12])

	for i := 0; i < 30; i++ {
		u := binary.LittleEndian.Uint16(buf[12+i*2 : 12+(i+1)*2])
		if u == 0 {
			break
		}
		tag.mid += string(u)
	}
	for i := 0; i < 50; i++ {
		u := binary.LittleEndian.Uint16(buf[72+i*2 : 72+(i+1)*2])
		if u == 0 {
			break
		}
		tag.mediafile += string(u)
	}

	tag.unknown_3 = binary.LittleEndian.Uint32(buf[173:177])
	tag.sizeof_struct = binary.LittleEndian.Uint32(buf[177:181])
	tag.version = binary.LittleEndian.Uint32(buf[181:185])
	tag.tag_magic = buf[185:193]

	return audioLen, nil
}