package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path"
	"strings"
)

type Song struct {
	Title  string
	Lyrics []string
	Path   string
	NR     string
}

type Album struct {
	Name    string
	Release string
	Path    string
	Songs   []Song
	Links   map[string]string
}

const ALBUM_DIR = "./data/albums/"

var albums []*Album

func parseAlbumName(fName string) (string, string) {
	s := strings.Split(fName, ".")
	s = strings.Split(s[0], "_")

	return s[0], strings.Join(s[1:], " ")
}

func ParseSong(s os.FileInfo, basePath string) Song {
	nr, title := parseAlbumName(s.Name())

	f, err := os.Open(path.Join(basePath, s.Name()))
	defer f.Close()

	if err != nil {
		log.Fatal(err)
	}

	content, err := ioutil.ReadAll(f)

	if err != nil {
		log.Fatal(err)
	}

	lyrics := strings.Split(string(content), "\n\n")

	song := Song{
		Title:  title,
		Lyrics: lyrics,
		Path:   strings.ToLower(strings.Replace(title, " ", "-", -1)),
		NR:     nr,
	}

	return song
}

func getSong(album *Album, title string) (Song, error) {
	for _, song := range album.Songs {
		if song.Path == strings.ToLower(title) {
			return song, nil
		}
	}

	return Song{}, io.EOF
}

func ParseAlbum(f os.FileInfo) *Album {
	year, name := parseAlbumName(f.Name())

	filen := path.Join(ROOT_DIR, ALBUM_DIR, f.Name())

	files, err := ioutil.ReadDir(filen)

	if err != nil {
		fmt.Printf("Error read songs: %s", err)
		log.Fatal(err)
	}

	album := Album{
		Name:    name,
		Path:    strings.ToLower(strings.Replace(name, " ", "-", -1)),
		Release: year,
	}

	for _, f := range files {
		if !strings.HasSuffix(f.Name(), ".lyric") {
			continue
		}
		album.Songs = append(album.Songs, ParseSong(f, filen))
	}

	fd, err := os.Open(path.Join(filen, "info.json"))
	defer fd.Close()

	if err != nil {
		fmt.Printf("Error info.json: %s", err)
		log.Fatal(err)
	}

	content, _ := ioutil.ReadAll(fd)

	json.Unmarshal(content, &album)

	return &album
}

func getAlbum(albums []*Album, title string) (*Album, error) {
	for _, album := range albums {
		if album.Path == strings.ToLower(title) {
			return album, nil
		}
	}

	return nil, io.EOF
}

func getAlbums() []*Album {
	if albums != nil {
		return albums
	}

	files, err := ioutil.ReadDir(path.Join(ROOT_DIR, ALBUM_DIR))

	if err != nil {
		log.Fatal(err)
	}

	for _, f := range files {
		if strings.HasPrefix(f.Name(), ".") {
			continue
		}
		albums = append(albums, ParseAlbum(f))
	}

	for i := len(albums)/2 - 1; i >= 0; i-- {
		opp := len(albums) - 1 - i
		albums[i], albums[opp] = albums[opp], albums[i]
	}

	return albums
}
