package view

import (
    "fmt"
    "net/http"
    "os"

    "arimelody-web/controller"
    "arimelody-web/model"
    "arimelody-web/templates"
)

// HTTP HANDLER METHODS

func MusicHandler(app *model.AppState) http.Handler {
    mux := http.NewServeMux()

    mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path == "/" {
            ServeCatalog(app).ServeHTTP(w, r)
            return
        }

        release, err := controller.GetRelease(app.DB, r.URL.Path[1:], true)
        if err != nil {
            http.NotFound(w, r)
            return
        }

        ServeGateway(app, release).ServeHTTP(w, r)
    }))

    return mux
}

func ServeCatalog(app *model.AppState) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        releases, err := controller.GetAllReleases(app.DB, true, 0, true)
        if err != nil {
            fmt.Printf("WARN: Failed to pull releases for catalog: %s\n", err)
            http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
            return
        }

        for _, release := range releases {
            if !release.IsReleased() {
                release.ReleaseType = model.Upcoming
            }
        }

        err = templates.MusicTemplate.Execute(w, releases)
        if err != nil {
            http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
        }
    })
}

func ServeGateway(app *model.AppState, release *model.Release) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // only allow authorised users to view hidden releases
        privileged := false
        if !release.Visible {
            session, err := controller.GetSessionFromRequest(app, r)
            if err != nil {
                fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session: %v\n", err)
                http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
                return
            }

            if session != nil && session.Account != nil {
                // TODO: check privilege on release
                privileged = true
            }

            if !privileged {
                http.NotFound(w, r)
                return
            }
        }

        response := *release

        if release.IsReleased() || privileged {
            response.Tracks = release.Tracks
            response.Credits = release.Credits
            response.Links = release.Links
        }

        err := templates.MusicGatewayTemplate.Execute(w, response)

        if err != nil {
            fmt.Printf("Error rendering music gateway for %s: %s\n", release.ID, err)
            http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
            return
        }
    })
}
