// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tag

import (
	"os"
	"testing"
)

type testMetadata struct {
	Album       string
	AlbumArtist string
	Artist      string
	Comment     string
	Composer    string
	Disc        int
	DiscTotal   int
	Genre       string
	Lyrics      string
	Title       string
	Track       int
	TrackTotal  int
	Year        int
}

var emptyMetadata = testMetadata{}
var fullMetadata = testMetadata{
	Album:       "Test Album",
	AlbumArtist: "Test AlbumArtist",
	Artist:      "Test Artist",
	Composer:    "Test Composer",
	Disc:        2,
	DiscTotal:   0,
	Genre:       "Jazz",
	Lyrics:      "",
	Title:       "Test Title",
	Track:       3,
	TrackTotal:  6,
	Year:        2000,
}
var mp3id3v11Metadata = testMetadata{
	Album:  "Test Album",
	Artist: "Test Artist",
	Genre:  "Jazz",
	Lyrics: "",
	Title:  "Test Title",
	Track:  3,
	Year:   2000,
}

func TestReadFrom(t *testing.T) {
	testdata := map[string]testMetadata{
		"with_tags/sample.flac":       fullMetadata,
		"with_tags/sample.id3v11.mp3": mp3id3v11Metadata,
		"with_tags/sample.id3v22.mp3": fullMetadata,
		"with_tags/sample.id3v23.mp3": fullMetadata,
		"with_tags/sample.id3v24.mp3": fullMetadata,
		"with_tags/sample.m4a":        fullMetadata,
		"with_tags/sample.mp4":        fullMetadata,
		"with_tags/sample.ogg":        fullMetadata,
		"without_tags/sample.flac":    emptyMetadata,
		"without_tags/sample.m4a":     emptyMetadata,
		"without_tags/sample.mp3":     emptyMetadata,
		"without_tags/sample.mp4":     emptyMetadata,
		"without_tags/sample.ogg":     emptyMetadata,
	}

	for path, metadata := range testdata {
		if err := test(t, path, metadata); err != nil {

			// mp3 id3v11 returns an err if it doesn't find any tags
			if err != ErrNoTagsFound && path != "without_tags/sample.mp3" {
				t.Error(err)
			}

		}
	}
}

func test(t *testing.T, path string, metadata testMetadata) error {
	f, err := os.Open("testdata/" + path)
	if err != nil {
		return err
	}
	defer f.Close()

	m, err := ReadFrom(f)
	if err != nil {
		return err
	}
	compareMetadata(t, m, metadata)
	return nil
}

func compareMetadata(t *testing.T, m Metadata, tt testMetadata) {
	testValue(t, tt.Album, m.Album())
	testValue(t, tt.AlbumArtist, m.AlbumArtist())
	testValue(t, tt.Artist, m.Artist())
	testValue(t, tt.Composer, m.Composer())
	testValue(t, tt.Genre, m.Genre())
	testValue(t, tt.Lyrics, m.Lyrics())
	testValue(t, tt.Title, m.Title())
	testValue(t, tt.Year, m.Year())

	disc, discTotal := m.Disc()
	testValue(t, tt.Disc, disc)
	testValue(t, tt.DiscTotal, discTotal)

	track, trackTotal := m.Track()
	testValue(t, tt.Track, track)
	testValue(t, tt.TrackTotal, trackTotal)
}

func testValue(t *testing.T, expected interface{}, found interface{}) {
	if expected != found {
		t.Errorf("expected '%v', found '%v'", expected, found)
	}
}
