package ximalaya

import (
	"bytes"
	"fmt"
	"io"

	"unlock-music.dev/cli/algo/common"
	"unlock-music.dev/cli/internal/sniff"
)

type Decoder struct {
	rd     io.ReadSeeker
	offset int

	audio io.Reader
}

func NewDecoder(p *common.DecoderParams) common.Decoder {
	return &Decoder{rd: p.Reader}
}

func (d *Decoder) Validate() error {
	encryptedHeader := make([]byte, x2mHeaderSize)
	if _, err := io.ReadFull(d.rd, encryptedHeader); err != nil {
		return fmt.Errorf("ximalaya read header: %w", err)
	}

	{ // try to decode with x2m
		header := decryptX2MHeader(encryptedHeader)
		if _, ok := sniff.AudioExtension(header); ok {
			d.audio = io.MultiReader(bytes.NewReader(header), d.rd)
			return nil
		}
	}

	{ // try to decode with x3m
		// not read file again, since x2m and x3m have the same header size
		header := decryptX3MHeader(encryptedHeader)
		if _, ok := sniff.AudioExtension(header); ok {
			d.audio = io.MultiReader(bytes.NewReader(header), d.rd)
			return nil
		}
	}

	return fmt.Errorf("ximalaya: unknown format")
}

func (d *Decoder) Read(p []byte) (n int, err error) {
	return d.audio.Read(p)
}

func init() {
	common.RegisterDecoder("x2m", false, NewDecoder)
	common.RegisterDecoder("x3m", false, NewDecoder)
	common.RegisterDecoder("xm", false, NewDecoder)
}