package monstersirenfetch_test

import (
	_ "embed"
	"encoding/json"
	"os"
	"reflect"
	"testing"

	. "git.gensokyo.uk/yonah/monstersirenfetch"
)

func TestFlatten(t *testing.T) {
	testCases := []struct {
		name      string
		albumData AlbumsData
		songsData SongsData
		want      CompositeAlbumsMap
		wantErr   error
	}{
		{"album conflict", AlbumsData{
			{CID: 9378, Name: "ARKnoNIGHTS", CoverURL: "https://web.hycdn.cn/siren/pic/20250401/83fc9e8a75ef3ac003e5d81dbd0f63fd.jpg", Artists: []string{"塞壬唱片-MSR"}},
			{CID: 9378, Name: "\x00"},
		}, SongsData{List: []Song{
			{CID: 697605, Name: "Tower Attack!", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 880313, Name: "(Re)union stream", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
		}}, nil, &AlbumConflictError{
			Index:    1,
			Previous: Album{CID: 9378, Name: "ARKnoNIGHTS", CoverURL: "https://web.hycdn.cn/siren/pic/20250401/83fc9e8a75ef3ac003e5d81dbd0f63fd.jpg", Artists: []string{"塞壬唱片-MSR"}},
			Current:  Album{CID: 9378, Name: "\x00"},
		}},

		{"song conflict", AlbumsData{
			{CID: 9378, Name: "ARKnoNIGHTS", CoverURL: "https://web.hycdn.cn/siren/pic/20250401/83fc9e8a75ef3ac003e5d81dbd0f63fd.jpg", Artists: []string{"塞壬唱片-MSR"}},
		}, SongsData{List: []Song{
			{CID: 697605, Name: "\x00", AlbumCID: 9378},

			{CID: 697605, Name: "Tower Attack!", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 880313, Name: "(Re)union stream", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
		}}, nil, &SongConflictError{
			Index:    1,
			Previous: &Song{CID: 697605, Name: "\x00", AlbumCID: 9378},
			Current:  Song{CID: 697605, Name: "Tower Attack!", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
		}},

		{"no album", AlbumsData{
			{CID: 9378, Name: "ARKnoNIGHTS", CoverURL: "https://web.hycdn.cn/siren/pic/20250401/83fc9e8a75ef3ac003e5d81dbd0f63fd.jpg", Artists: []string{"塞壬唱片-MSR"}},
		}, SongsData{List: []Song{
			{CID: 461133, Name: "相见欢", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},

			{CID: 697605, Name: "Tower Attack!", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 880313, Name: "(Re)union stream", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
		}}, nil, os.ErrNotExist},

		{"valid", AlbumsData{
			{CID: 230, Name: "相见欢OST", CoverURL: "https://web.hycdn.cn/siren/pic/20250124/c3ece0f3dca2297441e9f788db248be6.png", Artists: []string{"塞壬唱片-MSR"}},
			{CID: 9378, Name: "ARKnoNIGHTS", CoverURL: "https://web.hycdn.cn/siren/pic/20250401/83fc9e8a75ef3ac003e5d81dbd0f63fd.jpg", Artists: []string{"塞壬唱片-MSR"}},
		}, SongsData{List: []Song{
			{CID: 779470, Name: "天下一白", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 953962, Name: "枯枰竞", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 48781, Name: "火曜门楹", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 880315, Name: "百里灶燃", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 461133, Name: "相见欢", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},

			{CID: 697605, Name: "Tower Attack!", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
			{CID: 880313, Name: "(Re)union stream", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
		}}, CompositeAlbumsMap{
			230: {
				Album: &Album{CID: 230, Name: "相见欢OST", CoverURL: "https://web.hycdn.cn/siren/pic/20250124/c3ece0f3dca2297441e9f788db248be6.png", Artists: []string{"塞壬唱片-MSR"}},
				Songs: SongsMap{
					779470: {CID: 779470, Name: "天下一白", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
					953962: {CID: 953962, Name: "枯枰竞", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
					48781:  {CID: 48781, Name: "火曜门楹", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
					880315: {CID: 880315, Name: "百里灶燃", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
					461133: {CID: 461133, Name: "相见欢", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
				},
			},
			9378: {
				Album: &Album{CID: 9378, Name: "ARKnoNIGHTS", CoverURL: "https://web.hycdn.cn/siren/pic/20250401/83fc9e8a75ef3ac003e5d81dbd0f63fd.jpg", Artists: []string{"塞壬唱片-MSR"}},
				Songs: SongsMap{
					697605: {CID: 697605, Name: "Tower Attack!", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
					880313: {CID: 880313, Name: "(Re)union stream", AlbumCID: 9378, Artists: []string{"塞壬唱片-MSR"}},
				},
			},
		}, nil},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			got, err := Flatten(tc.albumData, tc.songsData)
			if !reflect.DeepEqual(err, tc.wantErr) {
				t.Errorf("Flaten: error = %v, want %v", err, tc.wantErr)
			}
			if !reflect.DeepEqual(got, tc.want) {
				t.Errorf("Flatten:\n%s\nwant\n%s", got, tc.want)
			}
		})
	}
}

//go:embed testdata/composite
var compositeWant string

func TestCompositeString(t *testing.T) {
	t.Run("album conflict", func(t *testing.T) {
		const want = "album CID conflict on index 3735928559: previous album 相见欢OST, current album ARKnoNIGHTS"
		if got := (&AlbumConflictError{
			Index:    0xdeadbeef,
			Previous: Album{CID: 230, Name: "相见欢OST", CoverURL: "https://web.hycdn.cn/siren/pic/20250124/c3ece0f3dca2297441e9f788db248be6.png", Artists: []string{"塞壬唱片-MSR"}},
			Current:  Album{CID: 9378, Name: "ARKnoNIGHTS", CoverURL: "https://web.hycdn.cn/siren/pic/20250401/83fc9e8a75ef3ac003e5d81dbd0f63fd.jpg", Artists: []string{"塞壬唱片-MSR"}},
		}).Error(); got != want {
			t.Errorf("Error: %q, want %q", got, want)
		}
	})

	t.Run("song conflict", func(t *testing.T) {
		const want = "song CID conflict on index 3735928559: previous song 天下一白, current song 枯枰竞"
		if got := (&SongConflictError{
			Index:    0xdeadbeef,
			Previous: &Song{CID: 779470, Name: "天下一白", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
			Current:  Song{CID: 953962, Name: "枯枰竞", AlbumCID: 230, Artists: []string{"塞壬唱片-MSR"}},
		}).Error(); got != want {
			t.Errorf("Error: %q, want %q", got, want)
		}
	})

	t.Run("zero", func(t *testing.T) {
		got := make(CompositeAlbumsMap).String()
		if got != "<empty>" {
			t.Errorf("String: %q", got)
		}
	})

	t.Run("sample", func(t *testing.T) {
		var (
			albumsResp AlbumsResponse
			songsResp  SongsResponse
		)

		if err := json.Unmarshal(albumsJSON, &albumsResp); err != nil {
			t.Fatalf("Unmarshal: error = %v", err)
		}
		if err := json.Unmarshal(songsJSON, &songsResp); err != nil {
			t.Fatalf("Unmarshal: error = %v", err)
		}

		var got string
		if m, err := Flatten(albumsResp.Data, songsResp.Data); err != nil {
			t.Fatalf("Flatten: error = %v", err)
		} else {
			got = m.String()
		}

		if got != compositeWant {
			t.Errorf("String:\n%s\nwant\n%s", got, compositeWant)
		}
	})
}
