package monstersirenfetch_test

import (
	_ "embed"
	"errors"
	"os"
	"reflect"
	"testing"

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

var (
	//go:embed testdata/album.data.json
	albumDataJSON []byte
	//go:embed testdata/album.detail.json
	albumDetailJSON []byte
)

func TestAlbum(t *testing.T) {
	checkJSONRoundTrip(t, AlbumResponse{Data: Album{
		CID:        1030,
		Name:       "Speed of Light",
		Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
		Belong:     "arknights",
		CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
		CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
		Artists:    []string{"塞壬唱片-MSR", "DJ Okawari"},
	}}, albumDataJSON)

	t.Run("copy", func(t *testing.T) {
		testCases := []struct {
			name    string
			a       *Album
			variant int
			want    Album
			wantOk  bool
		}{
			{"nil", nil, AlbumVariantDetail, Album{CID: -0xdeadbeef}, false},
			{"current", new(Album), AlbumVariantCurrent, Album{}, true},
			{"full guard", new(Album), AlbumVariantDetail, Album{CID: -0xdeadbeef}, false},

			{"current full", &Album{
				Belong: "\x00",
				Songs:  []AlbumSong{{}},
			}, AlbumVariantCurrent, Album{
				Belong: "\x00",
				Songs:  []AlbumSong{{}},
			}, true},

			{"oob", &Album{
				Belong: "\x00",
				Songs:  []AlbumSong{{}},
			}, 0xbad, Album{CID: -0xdeadbeef}, false},

			{"full", &Album{
				CID:        1030,
				Name:       "Speed of Light",
				Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
				Belong:     "arknights",
				CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
				CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Songs: []AlbumSong{
					{CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}},
					{CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}},
				},
				Artists: []string{"塞壬唱片-MSR", "DJ Okawari"},
			}, AlbumVariantFull, Album{
				CID:        1030,
				Name:       "Speed of Light",
				Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
				Belong:     "arknights",
				CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
				CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Songs: []AlbumSong{
					{CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}},
					{CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}},
				},
				Artists: []string{"塞壬唱片-MSR", "DJ Okawari"},
			}, true},

			{"detail", &Album{
				CID:        1030,
				Name:       "Speed of Light",
				Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
				Belong:     "arknights",
				CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
				CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Songs: []AlbumSong{
					{CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}},
					{CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}},
				},
				Artists: []string{"塞壬唱片-MSR", "DJ Okawari"},
			}, AlbumVariantDetail, Album{
				CID:        1030,
				Name:       "Speed of Light",
				Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
				Belong:     "arknights",
				CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
				CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Songs: []AlbumSong{
					{CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}},
					{CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}},
				},
			}, true},

			{"data", &Album{
				CID:        1030,
				Name:       "Speed of Light",
				Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
				Belong:     "arknights",
				CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
				CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Songs: []AlbumSong{
					{CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}},
					{CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}},
				},
				Artists: []string{"塞壬唱片-MSR", "DJ Okawari"},
			}, AlbumVariantData, Album{
				CID:        1030,
				Name:       "Speed of Light",
				Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
				Belong:     "arknights",
				CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
				CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Artists:    []string{"塞壬唱片-MSR", "DJ Okawari"},
			}, true},

			{"base", &Album{
				CID:        1030,
				Name:       "Speed of Light",
				Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
				Belong:     "arknights",
				CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
				CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Songs: []AlbumSong{
					{CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}},
					{CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}},
				},
				Artists: []string{"塞壬唱片-MSR", "DJ Okawari"},
			}, AlbumVariantBase, Album{
				CID:      1030,
				Name:     "Speed of Light",
				CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
				Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
			}, true},
		}
		for _, tc := range testCases {
			t.Run(tc.name, func(t *testing.T) {
				got := Album{CID: -0xdeadbeef}
				if ok := tc.a.Copy(&got, tc.variant); ok != tc.wantOk {
					t.Errorf("Copy: ok = %v, want %v", ok, tc.wantOk)
				}
				if !reflect.DeepEqual(got, tc.want) {
					t.Errorf("Copy: %#v, want %#v", got, tc.want)
				}
			})
		}
	})
}

func TestAlbumEnrich(t *testing.T) {
	testCases := []struct {
		name    string
		base    Album
		n       Net
		want    Album
		wantErr error
	}{
		{"get", Album{
			CID:      1030,
			Name:     "Speed of Light",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNet{}, Album{}, errors.New("url https://monster-siren.hypergryph.com/api/album/1030/detail requested, but is not present")},

		{"invalid response", Album{
			CID:      1030,
			Name:     "Speed of Light",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNet{
			makeAlbumPath(1030, true): []byte{0},
		}, Album{}, errors.Join(newSyntaxError("invalid character '\\x00' looking for beginning of value", 1))},

		{"close", Album{
			CID:      1030,
			Name:     "Speed of Light",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNetErrorCloser{
			makeAlbumPath(1030, true): albumDetailJSON,
		}, Album{}, os.ErrInvalid},

		{"inconsistent cid", Album{
			CID:      0xdeadbeef,
			Name:     "Speed of Light",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNet{
			makeAlbumPath(0xdeadbeef, true): albumDetailJSON,
		}, Album{}, &InconsistentEnrichError[StringInt]{
			Field:    "cid",
			Value:    0xdeadbeef,
			NewValue: 1030,
		}},

		{"inconsistent name", Album{
			CID:      1030,
			Name:     "Speed of Light\x00",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNet{
			makeAlbumPath(1030, true): albumDetailJSON,
		}, Album{}, &InconsistentEnrichError[string]{
			Field:    "name",
			Value:    "Speed of Light\x00",
			NewValue: "Speed of Light",
		}},

		{"inconsistent coverUrl", Album{
			CID:      1030,
			Name:     "Speed of Light",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg\x00",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNet{
			makeAlbumPath(1030, true): albumDetailJSON,
		}, Album{}, &InconsistentEnrichError[string]{
			Field:    "coverUrl",
			Value:    "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg\x00",
			NewValue: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
		}},

		{"unexpected artists", Album{
			CID:      1030,
			Name:     "Speed of Light",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNet{
			makeAlbumPath(1030, true): albumDataJSON,
		}, Album{}, &InconsistentEnrichError[[]string]{
			Field:    "artists",
			Value:    nil,
			NewValue: []string{"塞壬唱片-MSR", "DJ Okawari"},
		}},

		{"valid", Album{
			CID:      1030,
			Name:     "Speed of Light",
			CoverURL: "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Artists:  []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, stubNet{
			makeAlbumPath(1030, true): albumDetailJSON,
		}, Album{
			CID:        1030,
			Name:       "Speed of Light",
			Intro:      "在无人告知方向的黑夜里，独自以光速探寻正确的道路。 \n无论看待世界是简单，亦或是复杂，大地和天空始终让开始与结束相连。 \n《Speed of Light》，通过乐调铺陈的驰放与内敛感，希望能为您呈现超脱于现实的惬意想象空间。 \n愿您掌心的小小地图一直指引着前路。像光一样前行，如企鹅物流般永不停歇。",
			Belong:     "arknights",
			CoverDeURL: "https://web.hycdn.cn/siren/pic/20210322/0bf0d84e08b57acd2455b412224ba8e8.jpg",
			CoverURL:   "https://web.hycdn.cn/siren/pic/20210322/56cbcd1d0093d8ee8ee22bf6d68ab4a6.jpg",
			Songs: []AlbumSong{
				{CID: 880374, Name: "Speed of Light", Artists: []string{"塞壬唱片-MSR", "DJ Okawari"}},
				{CID: 125012, Name: "Speed of Light (Instrumental)", Artists: []string{"DJ Okawari"}},
			},
			Artists: []string{"塞壬唱片-MSR", "DJ Okawari"},
		}, nil},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			a := new(Album)
			*a = tc.base
			if err := a.Enrich(t.Context(), tc.n); !reflect.DeepEqual(err, tc.wantErr) {
				t.Errorf("Enrich: error = %v, want %v", err, tc.wantErr)
			}
			if tc.wantErr == nil && !reflect.DeepEqual(a, &tc.want) {
				t.Errorf("Enrich: %#v, want %#v", a, &tc.want)
			}
		})
	}

	t.Run("invalid", func(t *testing.T) {
		t.Run("nil", func(t *testing.T) {
			if err := (*Album)(nil).Enrich(t.Context(), nil); !errors.Is(err, os.ErrInvalid) {
				t.Errorf("Enrich: error = %v", err)
			}
		})
		t.Run("full", func(t *testing.T) {
			if err := (&Album{Belong: "\x00", Songs: []AlbumSong{{}}}).Enrich(t.Context(), nil); !errors.Is(err, os.ErrInvalid) {
				t.Errorf("Enrich: error = %v", err)
			}
		})
	})

}

func makeAlbumPath(cid StringInt, detail bool) string {
	suffix := "data"
	if detail {
		suffix = "detail"
	}
	return APIPrefix + "/album/" + cid.String() + "/" + suffix
}
