package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"math/rand"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/golang/glog"

	"code.hackerspace.pl/hscloud/hswaw/oodviewer/templates"
)

var (
	tplBase  = template.Must(template.New("base").Parse(string(templates.Data["base.html"])))
	tplTerm  = template.Must(template.Must(tplBase.Clone()).Parse(string(templates.Data["term.html"])))
	tplTerms = template.Must(template.Must(tplBase.Clone()).Parse(string(templates.Data["terms.html"])))
)

// handleTermsJson returns a JSON list of all terms.
func (a *app) handleTermsJson(w http.ResponseWriter, r *http.Request) {
	terms, err := a.getTerms(r.Context())
	if err != nil {
		glog.Errorf("getTerms: %v", err)
		w.WriteHeader(500)
		fmt.Fprintf(w, "internal error")
		return
	}
	// Target API from old oodviewer, even if it's terrible.
	var res [][]interface{}
	for _, term := range terms {
		res = append(res, []interface{}{
			term.Name, term.Entries,
		})
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(res)
}

// handleTerms renders a HTML page containing all terms.
func (a *app) handleTerms(w http.ResponseWriter, r *http.Request) {
	terms, err := a.getTerms(r.Context())
	if err != nil {
		glog.Errorf("getTerms: %v", err)
		w.WriteHeader(500)
		fmt.Fprintf(w, "internal error")
		return
	}

	termsData := make([]struct {
		URL   string
		Name  string
		Count uint64
	}, len(terms))

	for i, term := range terms {
		termsData[i].URL = "/term/" + url.QueryEscape(term.Name)
		termsData[i].Name = term.Name
		termsData[i].Count = term.Entries
	}

	tplTerms.Execute(w, map[string]interface{}{
		"Terms": termsData,
	})
}

// handleTermJson returns a JSON list of all entries contained within a term.
func (a *app) handleTermJson(w http.ResponseWriter, r *http.Request) {
	parts := strings.Split(r.URL.Path, "/")
	name := parts[len(parts)-1]

	entries, err := a.getEntries(r.Context(), name)
	if err != nil {
		glog.Errorf("getEntries: %v", err)
		w.WriteHeader(500)
		fmt.Fprintf(w, "internal error")
		return
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(entries)
}

// handleRandomTermJson returns a JSON serialized randomly chosen entry from a
// given term.
func (a *app) handleRandomTermJson(w http.ResponseWriter, r *http.Request) {
	parts := strings.Split(r.URL.Path, "/")
	name := parts[len(parts)-1]

	entries, err := a.getEntries(r.Context(), name)
	if err != nil {
		glog.Errorf("getEntries: %v", err)
		w.WriteHeader(500)
		fmt.Fprintf(w, "internal error")
		return
	}
	if len(entries) < 1 {
		w.WriteHeader(404)
		fmt.Fprintf(w, "no such entry")
		return
	}
	entry := entries[rand.Intn(len(entries))]
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(entry)
}

// handleTerm renders an HTML page of all entries contained within a term.
func (a *app) handleTerm(w http.ResponseWriter, r *http.Request) {
	parts := strings.Split(r.URL.Path, "/")
	name := parts[len(parts)-1]

	entries, err := a.getEntries(r.Context(), name)
	if err != nil {
		glog.Errorf("getEntries: %v", err)
		w.WriteHeader(500)
		fmt.Fprintf(w, "internal error")
		return
	}

	entriesData := make([]struct {
		Entry  string
		Author string
		Added  string
	}, len(entries))
	for i, entry := range entries {
		entriesData[i].Entry = entry.Entry
		entriesData[i].Author = entry.Author
		entriesData[i].Added = time.Unix(entry.Added, 0).String()
	}

	tplTerm.Execute(w, map[string]interface{}{
		"Name":    name,
		"Entries": entriesData,
	})
}
