package api

import (
	"encoding/json"
	"fmt"
	"net/http"

	"code.justin.tv/video/spectre/backend"
	"code.justin.tv/video/spectre/playhead"

	"github.com/zenazn/goji/web"
)

type Channel struct {
	ID               int                `json:"id"`
	Enabled          bool               `json:"enabled"`
	ActivePlaylistID int                `json:"active_playlist_id"`
	Active           bool               `json:"active"`
	Playlists        []backend.Playlist `json:"playlists"`
	Playhead         *playhead.Playhead `json:"playhead"`
}

func (T *Router) ShowChannel(c web.C, w http.ResponseWriter, r *http.Request) {
	channelID, err := idToInt(c.URLParams["channel_id"])
	if err != nil {
		T.ServeError(w, r, err)
		return
	}
	channelResponse := T.getChannelResponse(channelID, true)

	// For now support JSONP for web player requests on this endpoint
	jsonBytes, err := json.Marshal(channelResponse)
	if err != nil {
		T.ServeError(w, r, err)
		return
	}
	if r.URL.Query().Get("callback") != "" {
		w.Header().Set("Content-Type", "application/javascript")
		fmt.Fprintf(w, "%s(%s)", r.URL.Query().Get("callback"), jsonBytes)
	} else {
		w.Write(jsonBytes)
	}
}

func (T *Router) UpdateChannel(c web.C, w http.ResponseWriter, r *http.Request) {
	channelID, err := idToInt(c.URLParams["channel_id"])
	if err != nil {
		T.ServeError(w, r, err)
		return
	}

	err = T.AuthHandler.AuthorizeRequest(r.Header.Get("Authorization"), channelID, r, T.StatsdClient)
	if err != nil {
		T.ServeError(w, r, err)
		return
	}

	params := backend.ChannelParams{}
	err = json.NewDecoder(r.Body).Decode(&params)
	if err != nil {
		T.ServeError(w, r, err)
		return
	}
	params.ID = channelID

	err = T.Backend.UpdateChannel(params)
	if err != nil {
		T.ServeError(w, r, err)
		return
	}

	channelResponse := T.getChannelResponse(channelID, false)

	err = json.NewEncoder(w).Encode(channelResponse)
	if err != nil {
		T.ServeError(w, r, err)
	}
}

func (T *Router) getChannelResponse(channelID int, cached bool) Channel {
	var ch *backend.Channel
	var err error
	if cached {
		ch, err = T.Backend.GetChannel(channelID)
	} else {
		ch, err = T.Backend.GetChannelUncached(channelID)
	}
	if err != nil {
		return Channel{
			ID:               channelID,
			Enabled:          false,
			ActivePlaylistID: -1,
			Active:           false,
			Playlists:        make([]backend.Playlist, 0),
			Playhead:         nil,
		}
	}

	playlists, _ := T.Backend.GetPlaylists(channelID)
	p, _ := playhead.GetPlayhead(channelID)
	return Channel{
		ID:               ch.ID,
		Enabled:          ch.IsEnabled(),
		ActivePlaylistID: ch.ActivePlaylistID,
		Active:           ch.Active,
		Playlists:        playlists,
		Playhead:         p,
	}
}
