package main

import (
				"arimelody.me/arimelody.me/api/v1/music"

				"fmt"
				"os"
				"time"

				_ "github.com/lib/pq"
				"github.com/jmoiron/sqlx"
)

var schema =
`CREATE TABLE IF NOT EXISTS Artists (
				id SERIAL primary key,
				name text,
				website text
);

CREATE TABLE IF NOT EXISTS Albums (
				id varchar(64) primary key,
				title text not null,
				release_date date not null,
				artwork text,
				buyname text,
				buylink text,
				description text,
				lyrics text
);

CREATE TABLE IF NOT EXISTS AlbumLinks (
				album varchar(64) references Albums(id) on delete cascade,
				name text,
				url text,
				constraint albumlinks_pk primary key (album, name)
);

CREATE TABLE IF NOT EXISTS AlbumCredits (
				album varchar(64) references Albums(id) on delete cascade,
				artist int references Artists(id) on delete cascade,
				role text
				constraint albumcredits_pk primary key (album, artist, role)
);`

func PushArtist(db *sqlx.DB, artist music.Artist) {
				query := "SELECT count(*) FROM Artists WHERE name=$1"
				var count int
				err := db.Get(&count, query, artist.Name)
				if err != nil {
								fmt.Printf("error while pushing artist [%s] to the database: %v\n", artist.Name, err)
				}

				query = "INSERT INTO artists (name, website) VALUES ($1, $2)"
				if count != 0 {
								query = "UPDATE artists SET website=$2 WHERE name=$1"
				}

				fmt.Printf("saving artist [%s] to the database...", artist.Name)
				_, err = db.Exec(query, 
								&artist.Name,
								&artist.Website,
				)
				if err != nil {
								fmt.Printf("error while pushing artist [%s] to the database: %v\n", artist.Name, err)
				}
				fmt.Printf("done!\n")

				// defer db.Close()
}

func PushAlbum(db *sqlx.DB, album music.Album) {
				var count int
				err := db.Get(&count, "SELECT count(*) FROM Albums WHERE id=$1", album.Id)
				if err != nil {
								fmt.Printf("error while pushing album [%s] to the database: %v\n", album.Id, err)
				}

				artist_ids := map[string]int{};
				for _, credit := range album.Credits {
								if _, ok := artist_ids[credit.Artist.Name]; ok {
												continue;
								}
								var id int
								err := db.Get(&id, "SELECT id FROM Artists WHERE name=$1", credit.Artist.Name)
								if err != nil {
												continue;
								}
								artist_ids[credit.Artist.Name] = id
				}

				if count == 0 {
								fmt.Printf("creating album [%s]...", album.Id)

								tx := db.MustBegin()
								tx.MustExec("INSERT INTO Albums VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", &album.Id, &album.Title, album.ReleaseDate.Format("2-Jan-2006"), &album.Artwork, &album.Buyname, &album.Buylink, &album.Description, &album.Lyrics)
								for _, link := range album.Links {
												tx.MustExec("INSERT INTO AlbumLinks (album, name, url) VALUES ($1, $2, $3)", &album.Id, &link.Name, &link.Url)
								}
								for _, credit := range album.Credits {
												artist_id := artist_ids[credit.Artist.Name]
												tx.MustExec("INSERT INTO AlbumCredits (album, artist, role) VALUES ($1, $2, $3)", &album.Id, &artist_id, &credit.Role)
								}
								tx.Commit()

								fmt.Printf("done!\n")
								return;

				}

				fmt.Printf("updating album [%s]...", album.Id)

				tx := db.MustBegin()
				tx.MustExec("UPDATE Albums SET title=$2, release_date=$3, artwork=$4, buyname=$5, buylink=$6, description=$7, lyrics=$8 WHERE id=$1",
								&album.Id,
								&album.Title,
								album.ReleaseDate.Format("2-Jan-2006"),
								&album.Artwork,
								&album.Buyname,
								&album.Buylink,
								&album.Description,
								&album.Lyrics,
				)
				// we're just gonna completely fresh them because
				// like hell am i actually gonna comb through every
				// single one of these
				tx.MustExec("DELETE FROM AlbumLinks WHERE album=$1", &album.Id)
				tx.MustExec("DELETE FROM AlbumCredits WHERE album=$1", &album.Id)
				for _, link := range album.Links {
								tx.MustExec("INSERT INTO AlbumLinks (album, name, url) VALUES ($1, $2, $3)", &album.Id, &link.Name, &link.Url)
				}
				for _, credit := range album.Credits {
								artist_id := artist_ids[credit.Artist.Name]
								tx.MustExec("INSERT INTO AlbumCredits (album, artist, role) VALUES ($1, $2, $3)", &album.Id, &artist_id, &credit.Role)
				}
				tx.Commit()

				fmt.Printf("done!\n")
}

func InitDatabase() *sqlx.DB {
				db, err := sqlx.Connect("postgres", "user=arimimi dbname=arimelody password=fuckingpassword sslmode=disable")
				if err != nil {
								fmt.Fprintf(os.Stderr, "unable to create database connection pool: %v\n", err)
								os.Exit(1)
				}
				
				db.SetConnMaxLifetime(time.Minute * 3)
				db.SetMaxOpenConns(10)
				db.SetMaxIdleConns(10)

				// db.MustExec(schema)

				return db
}
