package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"sync"
	"time"

	"cloud.google.com/go/datastore"
	"github.com/unrolled/secure"
	"google.golang.org/api/iterator"

	"go.skia.org/infra/go/baseapp"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
)

const (
	STATUS_DS_KIND = "Status"

	OPEN_STATE    = "open"
	CAUTION_STATE = "caution"
	CLOSED_STATE  = "closed"
)

var (
	// Mutex that guards changes to the status datastore.
	statusMtx sync.RWMutex
)

// Status - A Tree status.
type Status struct {
	Date     time.Time `json:"date" datastore:"date"`
	Message  string    `json:"message" datastore:"message"`
	Rollers  string    `json:"rollers" datastore:"rollers"`
	Username string    `json:"username" datastore:"username"`

	// Only specified for backwards compatibility.
	FirstRev int `json:"first_rev,omitempty" datastore:"first_rev"`
	LastRev  int `json:"last_rev,omitempty" datastore:"last_rev"`

	// Should be one of open/closed/caution.
	GeneralState string `json:"general_state" datastore:"general_state,omitempty"`
}

func AddStatus(message, username, generalState, rollers string) error {
	s := &Status{
		Date:         time.Now(),
		Message:      message,
		Rollers:      rollers,
		Username:     username,
		GeneralState: generalState,
	}

	key := &datastore.Key{
		Kind:      STATUS_DS_KIND,
		Namespace: *namespace,
	}
	if _, err := dsClient.RunInTransaction(context.Background(), func(tx *datastore.Transaction) error {
		var err error
		if _, err = tx.Put(key, s); err != nil {
			return err
		}
		return nil
	}); err != nil {
		return fmt.Errorf("Failed to add status: %s", err)
	}
	return nil
}

func GetLatestStatus() (*Status, error) {
	statuses, err := GetStatuses(1)
	if err != nil {
		return nil, err
	}
	return statuses[0], nil
}

func GetStatuses(num int) ([]*Status, error) {
	statuses := []*Status{}
	q := datastore.NewQuery("Status").Namespace(*namespace).Order("-date").Limit(num)
	it := dsClient.Run(context.TODO(), q)
	for {
		s := &Status{}
		_, err := it.Next(s)
		if err == iterator.Done {
			break
		} else if err != nil {
			return nil, fmt.Errorf("Failed to retrieve list of statuses: %s", err)
		}
		statuses = append(statuses, s)
	}
	return statuses, nil
}

// HTTP Handlers

func (srv *Server) treeStateHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	if *baseapp.Local {
		srv.loadTemplates()
	}
	if err := srv.templates.ExecuteTemplate(w, "index.html", map[string]string{
		// Look in webpack.config.js for where the nonce templates are injected.
		"Nonce": secure.CSPNonce(r.Context()),
	}); err != nil {
		httputils.ReportError(w, err, "Failed to expand template.", http.StatusInternalServerError)
		return
	}
}

func (srv *Server) bannerStatusHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	statusMtx.RLock()
	defer statusMtx.RUnlock()

	statuses, err := GetStatuses(1)
	if err != nil {
		httputils.ReportError(w, err, "Failed to query for recent statuses.", http.StatusInternalServerError)
		return
	}
	var status interface{}
	if len(statuses) == 0 {
		status = map[string]string{}
	} else {
		// This is the weird python date format expected by the CQ. Eg: 2020-02-25 14:47:26.253187.
		d := statuses[0].Date
		expectedDateFormat := fmt.Sprintf("%d-%02d-%02d %02d:%02d:%02d.%06d", d.Year(), d.Month(), d.Day(), d.Hour(), d.Minute(), d.Second(), d.Nanosecond()/1000)
		status = struct {
			Username     string `json:"username"`
			Date         string `json:"date"`
			Message      string `json:"message"`
			GeneralState string `json:"general_state"`
		}{
			Username:     statuses[0].Username,
			Date:         expectedDateFormat,
			Message:      statuses[0].Message,
			GeneralState: statuses[0].GeneralState,
		}
	}
	if err := json.NewEncoder(w).Encode(status); err != nil {
		sklog.Errorf("Failed to send response: %s", err)
	}
}

func (srv *Server) recentStatusesHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	statusMtx.RLock()
	defer statusMtx.RUnlock()

	statuses, err := GetStatuses(25)
	if err != nil {
		httputils.ReportError(w, err, "Failed to query for recent statuses.", http.StatusInternalServerError)
		return
	}
	if err := json.NewEncoder(w).Encode(statuses); err != nil {
		sklog.Errorf("Failed to send response: %s", err)
	}
}

func (srv *Server) addStatusHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	user := srv.user(r)
	if !srv.modify.Member(user) {
		httputils.ReportError(w, nil, "You do not have access to set the tree status.", http.StatusInternalServerError)
		return
	}

	// Parse the request.
	m := struct {
		Message string `json:"message"`
		Rollers string `json:"rollers"`
	}{}
	if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
		httputils.ReportError(w, err, "Failed to decode request.", http.StatusInternalServerError)
		return
	}
	message := m.Message
	rollers := m.Rollers

	// Validate the message.
	containsOpenState := strings.Contains(strings.ToLower(message), OPEN_STATE)
	containsCautionState := strings.Contains(strings.ToLower(message), CAUTION_STATE)
	containsClosedState := strings.Contains(strings.ToLower(message), CLOSED_STATE)
	if (containsOpenState && containsCautionState) ||
		(containsCautionState && containsClosedState) ||
		(containsClosedState && containsOpenState) {
		httputils.ReportError(w, nil, fmt.Sprintf("Cannot specify two keywords from (%s, %s, %s) in a status message.", OPEN_STATE, CAUTION_STATE, CLOSED_STATE), http.StatusBadRequest)
		return
	} else if !(containsOpenState || containsCautionState || containsClosedState) {
		httputils.ReportError(w, nil, fmt.Sprintf("Must specify either (%s, %s, %s) somewhere in the status message.", OPEN_STATE, CAUTION_STATE, CLOSED_STATE), http.StatusBadRequest)
		return
	} else if containsOpenState && rollers != "" {
		httputils.ReportError(w, nil, fmt.Sprintf("Waiting for rollers should only be used with %s or %s states", CAUTION_STATE, CLOSED_STATE), http.StatusBadRequest)
		return
	}

	// Figure out the state.
	var generalState string
	if containsClosedState {
		generalState = CLOSED_STATE
	} else if containsCautionState {
		generalState = CAUTION_STATE
	} else {
		generalState = OPEN_STATE
	}

	statusMtx.Lock()
	defer statusMtx.Unlock()

	// Stop watching any previously defined autorollers.
	StopWatchingAutorollers()
	// Add status to datastore.
	if err := AddStatus(message, user, generalState, rollers); err != nil {
		httputils.ReportError(w, err, "Failed to add message to the datastore", http.StatusInternalServerError)
		return
	}
	// Start watching any newly defined autorollers.
	StartWatchingAutorollers(rollers)

	// Return updated list of the most recent tree statuses.
	statuses, err := GetStatuses(25)
	if err != nil {
		httputils.ReportError(w, err, "Failed to query for recent statuses.", http.StatusInternalServerError)
		return
	}
	if err := json.NewEncoder(w).Encode(statuses); err != nil {
		sklog.Errorf("Failed to send response: %s", err)
		return
	}
}
