package icecast

import (
	"bytes"
	"io"
	"testing"
)

func TestParseICYMetadataExtractsStreamTitle(t *testing.T) {
	meta := parseICYMetadata([]byte("StreamTitle='Artist - Track';StreamUrl='';"))
	if meta.StreamTitle != "Artist - Track" {
		t.Fatalf("streamTitle=%q want %q", meta.StreamTitle, "Artist - Track")
	}
}

func TestICYReaderStripsMetadataAndEmitsTitle(t *testing.T) {
	block := buildICYMetadataBlock("StreamTitle='Unit Test';")
	wire := append([]byte("ABCD"), byte(len(block)/16))
	wire = append(wire, block...)
	wire = append(wire, []byte("EFGH")...)

	var got icyMetadata
	r := newICYReader(bytes.NewReader(wire), 4, func(meta icyMetadata) {
		got = meta
	})

	audio, err := io.ReadAll(r)
	if err != nil {
		t.Fatalf("read: %v", err)
	}
	if string(audio) != "ABCDEFGH" {
		t.Fatalf("audio=%q want %q", string(audio), "ABCDEFGH")
	}
	if got.StreamTitle != "Unit Test" {
		t.Fatalf("streamTitle=%q want %q", got.StreamTitle, "Unit Test")
	}
}

func TestParseICYMetaInt(t *testing.T) {
	tests := []struct {
		name    string
		in      string
		want    int
		wantErr bool
	}{
		{name: "empty", in: "", want: 0},
		{name: "valid", in: "16000", want: 16000},
		{name: "invalid", in: "x", wantErr: true},
		{name: "negative", in: "-1", wantErr: true},
	}
	for _, tc := range tests {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			got, err := parseICYMetaInt(tc.in)
			if tc.wantErr {
				if err == nil {
					t.Fatalf("expected error for %q", tc.in)
				}
				return
			}
			if err != nil {
				t.Fatalf("parse: %v", err)
			}
			if got != tc.want {
				t.Fatalf("got=%d want %d", got, tc.want)
			}
		})
	}
}

func buildICYMetadataBlock(raw string) []byte {
	b := []byte(raw)
	if rem := len(b) % 16; rem != 0 {
		b = append(b, bytes.Repeat([]byte{0x00}, 16-rem)...)
	}
	return b
}
