// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Package som implements HTTP server that handles requests to default module.
package som

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"

	"golang.org/x/net/context"

	"github.com/luci/gae/service/datastore"
	"github.com/luci/gae/service/info"
	"github.com/luci/gae/service/memcache"
	"github.com/luci/luci-go/appengine/gaeauth/server"
	"github.com/luci/luci-go/appengine/gaeauth/server/gaesigner"
	"github.com/luci/luci-go/appengine/gaemiddleware"
	"github.com/luci/luci-go/common/logging"
	"github.com/luci/luci-go/common/tsmon/metric"
	"github.com/luci/luci-go/server/auth"
	"github.com/luci/luci-go/server/auth/identity"
	"github.com/luci/luci-go/server/auth/xsrf"
	"github.com/luci/luci-go/server/router"
	"github.com/luci/luci-go/server/settings"
)

const (
	authGroup           = "sheriff-o-matic-access"
	annotationsCacheKey = "annotation-metadata"
	bugQueueCacheFormat = "bugqueue-%s"
	settingsKey         = "tree"
	// annotations will expire after this amount of time
	annotationExpiration  = time.Hour * 24 * 10
	productionAnalyticsID = "UA-55762617-1"
	stagingAnalyticsID    = "UA-55762617-22"
)

var (
	mainPage         = template.Must(template.ParseFiles("./index.html"))
	accessDeniedPage = template.Must(template.ParseFiles("./access-denied.html"))
	monorailEndpoint = "https://monorail-prod.appspot.com/_ah/api/monorail/v1/"
	jsErrors         = metric.NewCounter("frontend/js_errors",
		"Number of uncaught javascript errors.", nil)
)

var errStatus = func(c context.Context, w http.ResponseWriter, status int, msg string) {
	logging.Errorf(c, "Status %d msg %s", status, msg)
	w.WriteHeader(status)
	w.Write([]byte(msg))
}

func indexPage(ctx *router.Context) {
	c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
	if p.ByName("path") == "" {
		http.Redirect(w, r, "/chromium", http.StatusFound)
		return
	}

	user := auth.CurrentIdentity(c)

	if user.Kind() == identity.Anonymous {
		url, err := auth.LoginURL(c, p.ByName("path"))
		if err != nil {
			errStatus(c, w, http.StatusInternalServerError, fmt.Sprintf(
				"You must login. Additionally, an error was encountered while serving this request: %s", err.Error()))
		} else {
			http.Redirect(w, r, url, http.StatusFound)
		}

		return
	}

	isGoogler, err := auth.IsMember(c, authGroup)

	if err != nil {
		errStatus(c, w, http.StatusInternalServerError, err.Error())
		return
	}

	logoutURL, err := auth.LogoutURL(c, "/")

	if err != nil {
		errStatus(c, w, http.StatusInternalServerError, err.Error())
		return
	}

	if !isGoogler {
		err = accessDeniedPage.Execute(w, map[string]interface{}{
			"Group":     authGroup,
			"LogoutURL": logoutURL,
		})
		if err != nil {
			logging.Errorf(c, "while rendering index: %s", err)
		}
		return
	}

	tok, err := xsrf.Token(c)
	if err != nil {
		logging.Errorf(c, "while getting xrsf token: %s", err)
	}

	AnalyticsID := stagingAnalyticsID
	if !strings.HasSuffix(info.AppID(c), "-staging") {
		logging.Debugf(c, "Using production GA ID for app %s", info.AppID(c))
		AnalyticsID = productionAnalyticsID
	}

	data := map[string]interface{}{
		"User":           user.Email(),
		"LogoutUrl":      logoutURL,
		"IsDevAppServer": info.IsDevAppServer(c),
		"XsrfToken":      tok,
		"AnalyticsID":    AnalyticsID,
	}

	err = mainPage.Execute(w, data)
	if err != nil {
		logging.Errorf(c, "while rendering index: %s", err)
	}
}

func getTreesHandler(ctx *router.Context) {
	c, w := ctx.Context, ctx.Writer

	q := datastore.NewQuery("Tree")
	results := []*Tree{}
	err := datastore.GetAll(c, q, &results)
	if err != nil {
		errStatus(c, w, http.StatusInternalServerError, err.Error())
		return
	}

	txt, err := json.Marshal(results)
	if err != nil {
		errStatus(c, w, http.StatusInternalServerError, err.Error())
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(txt)
}

// Switches chromium.org emails for google.com emails and vice versa.
// Note that chromium.org emails may be different from google.com emails.
func getAlternateEmail(email string) string {
	s := strings.Split(email, "@")
	if len(s) != 2 {
		return email
	}

	user, domain := s[0], s[1]
	if domain == "chromium.org" {
		return fmt.Sprintf("%s@google.com", user)
	}
	return fmt.Sprintf("%s@chromium.org", user)
}

func getCrRevJSON(c context.Context, pos string) (map[string]string, error) {
	itm := memcache.NewItem(c, fmt.Sprintf("crrev:%s", pos))
	err := memcache.Get(c, itm)

	if err == memcache.ErrCacheMiss {
		hc, err := getOAuthClient(c)
		if err != nil {
			return nil, err
		}

		resp, err := hc.Get(fmt.Sprintf("https://cr-rev.appspot.com/_ah/api/crrev/v1/redirect/%s", pos))
		if err != nil {
			return nil, err
		}

		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return nil, err
		}
		itm.SetValue(body)
		if err = memcache.Set(c, itm); err != nil {
			return nil, fmt.Errorf("while setting memcache: %s", err)
		}
	} else if err != nil {
		return nil, fmt.Errorf("while getting from memcache: %s", err)
	}

	m := map[string]string{}
	err = json.Unmarshal(itm.Value(), &m)
	if err != nil {
		return nil, err
	}

	return m, nil
}

func getRevRangeHandler(ctx *router.Context) {
	c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params

	start := p.ByName("start")
	end := p.ByName("end")
	if start == "" || end == "" {
		errStatus(c, w, http.StatusBadRequest, "Start and end parameters must be set.")
		return
	}

	itm := memcache.NewItem(c, fmt.Sprintf("revrange:%s..%s", start, end))
	err := memcache.Get(c, itm)

	if err == memcache.ErrCacheMiss {
		startRev, err := getCrRevJSON(c, start)
		if err != nil {
			errStatus(c, w, http.StatusInternalServerError, err.Error())
			return
		}

		endRev, err := getCrRevJSON(c, end)
		if err != nil {
			errStatus(c, w, http.StatusInternalServerError, err.Error())
			return
		}

		// TODO(seanmccullough): some sanity checking of the rev json (same repo etc)

		gitilesURL := fmt.Sprintf("https://chromium.googlesource.com/chromium/src/+log/%s^..%s?format=JSON",
			startRev["git_sha"], endRev["git_sha"])

		itm.SetValue([]byte(gitilesURL))
		if err = memcache.Set(c, itm); err != nil {
			errStatus(c, w, http.StatusInternalServerError, fmt.Sprintf("while setting memcache: %s", err))
			return
		}
	} else if err != nil {
		errStatus(c, w, http.StatusInternalServerError, fmt.Sprintf("while getting memcache: %s", err))
		return
	}

	http.Redirect(w, r, string(itm.Value()), 301)
}

type eCatcherReq struct {
	Errors    map[string]int64 `json:"errors"`
	XSRFToken string           `json:"xsrf_token"`
}

func postClientMonHandler(ctx *router.Context) {
	c, w, r := ctx.Context, ctx.Writer, ctx.Request

	req := &eCatcherReq{}
	if err := json.NewDecoder(r.Body).Decode(req); err != nil {
		errStatus(c, w, http.StatusBadRequest, err.Error())
		return
	}

	if err := xsrf.Check(c, req.XSRFToken); err != nil {
		errStatus(c, w, http.StatusForbidden, err.Error())
		return
	}

	for _, errCount := range req.Errors {
		jsErrors.Add(c, errCount)
	}
	logging.Errorf(c, "clientmon report: %v", req.Errors)
}
func getTreeLogoHandler(ctx *router.Context) {
	c, w := ctx.Context, ctx.Writer

	sa, err := info.ServiceAccount(c)
	if err != nil {
		logging.Errorf(c, "failed to get service account: %v", err)
		errStatus(c, w, http.StatusInternalServerError, err.Error())
		return
	}

	getTreeLogo(ctx, sa, gaesigner.Signer{})
}

type signer interface {
	SignBytes(c context.Context, b []byte) (string, []byte, error)
}

func getTreeLogo(ctx *router.Context, sa string, sign signer) {
	c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
	tree := p.ByName("tree")
	resource := fmt.Sprintf("/%s.appspot.com/logos/%s.png", info.AppID(c), tree)
	expStr := fmt.Sprintf("%d", time.Now().Add(10*time.Minute).Unix())
	sl := []string{
		"GET",
		"", // Optional MD5, which we don't have.
		"", // Content type, ommitted because it breaks the signature.
		expStr,
		resource,
	}
	unsigned := strings.Join(sl, "\n")
	_, b, err := sign.SignBytes(c, []byte(unsigned))
	if err != nil {
		logging.Errorf(c, "failed to sign bytes: %v", err)
		errStatus(c, w, http.StatusInternalServerError, err.Error())
		return
	}
	sig := base64.StdEncoding.EncodeToString(b)
	params := url.Values{
		"GoogleAccessId": {sa},
		"Expires":        {expStr},
		"Signature":      {sig},
	}

	signedURL := fmt.Sprintf("https://storage.googleapis.com%s?%s", resource, params.Encode())
	http.Redirect(w, r, signedURL, http.StatusFound)
}

// getOAuthClient returns a client capable of making HTTP requests authenticated
// with OAuth access token for userinfo.email scope.
var getOAuthClient = func(c context.Context) (*http.Client, error) {
	// Note: "https://www.googleapis.com/auth/userinfo.email" is the default
	// scope used by GetRPCTransport(AsSelf). Use auth.WithScopes(...) option to
	// override.
	t, err := auth.GetRPCTransport(c, auth.AsSelf)
	if err != nil {
		return nil, err
	}
	return &http.Client{Transport: t}, nil
}

// base is the root of the middleware chain.
func base(includeCookie bool) router.MiddlewareChain {
	methods := []auth.Method{
		&server.OAuth2Method{Scopes: []string{server.EmailScope}},
		&server.InboundAppIDAuthMethod{},
	}
	if includeCookie {
		methods = append(methods, server.CookieAuth)
	}

	return gaemiddleware.BaseProd().Extend(
		auth.Use(methods),
		auth.Authenticate,
	)
}

func requireGoogler(c *router.Context, next router.Handler) {
	isGoogler, err := auth.IsMember(c.Context, authGroup)
	switch {
	case err != nil:
		errStatus(c.Context, c.Writer, http.StatusInternalServerError, err.Error())
	case !isGoogler:
		errStatus(c.Context, c.Writer, http.StatusForbidden, "Access denied")
	default:
		next(c)
	}
}

func noopHandler(ctx *router.Context) {
	return
}

func getXSRFToken(ctx *router.Context) {
	c, w := ctx.Context, ctx.Writer

	tok, err := xsrf.Token(c)
	if err != nil {
		logging.Errorf(c, "while getting xrsf token: %s", err)
	}

	data := map[string]string{
		"token": tok,
	}
	txt, err := json.Marshal(data)
	if err != nil {
		errStatus(c, w, http.StatusInternalServerError, err.Error())
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(txt)
}

//// Routes.
func init() {

	settings.RegisterUIPage(settingsKey, settingsUIPage{})

	r := router.New()
	basemw := base(true)

	protected := basemw.Extend(requireGoogler)

	gaemiddleware.InstallHandlers(r, gaemiddleware.BaseProd())
	r.GET("/api/v1/trees/", protected, getTreesHandler)
	r.GET("/api/v1/alerts/:tree", protected, getAlertsHandler)
	r.GET("/api/v1/pubsubalerts/:tree", protected, getPubSubAlertsHandler)
	r.GET("/api/v1/restarts/:tree", protected, getRestartingMastersHandler)
	r.GET("/api/v1/xsrf_token", protected, getXSRFToken)

	// Disallow cookies because this handler should not be accessible by regular
	// users.
	r.POST("/api/v1/alerts/:tree", basemw, postAlertsHandler)
	r.GET("/api/v1/annotations/", protected, getAnnotationsHandler)
	r.POST("/api/v1/annotations/:annKey/:action", protected, postAnnotationsHandler)
	r.GET("/api/v1/bugqueue/:label", protected, getBugQueueHandler)
	r.GET("/api/v1/bugqueue/:label/uncached/", protected, getUncachedBugsHandler)
	r.GET("/api/v1/revrange/:start/:end", basemw, getRevRangeHandler)
	r.GET("/logos/:tree", protected, getTreeLogoHandler)
	r.GET("/alertdiff/:tree", protected, getMiloDiffHandler)

	// Non-public endpoints.
	r.GET("/_cron/refresh/bugqueue/:label", basemw, refreshBugQueueHandler)
	r.GET("/_cron/annotations/flush_old/", basemw, flushOldAnnotationsHandler)
	r.GET("/_cron/annotations/refresh/", basemw, refreshAnnotationsHandler)
	r.GET("/_cron/analyze/:tree", basemw, getAnalyzeHandler)
	r.POST("/_/clientmon", basemw, postClientMonHandler)
	r.POST("/_ah/push-handlers/milo", basemw, postMiloPubSubHandler)

	// Ingore reqeuests from builder-alerts rather than 404.
	r.GET("/alerts", gaemiddleware.BaseProd(), noopHandler)
	r.POST("/alerts", gaemiddleware.BaseProd(), noopHandler)

	rootRouter := router.New()
	rootRouter.GET("/*path", basemw, indexPage)

	http.DefaultServeMux.Handle("/_cron/", r)
	http.DefaultServeMux.Handle("/api/", r)
	http.DefaultServeMux.Handle("/admin/", r)
	http.DefaultServeMux.Handle("/auth/", r)
	http.DefaultServeMux.Handle("/_ah/", r)
	http.DefaultServeMux.Handle("/internal/", r)
	http.DefaultServeMux.Handle("/_/", r)
	http.DefaultServeMux.Handle("/logos/", r)
	http.DefaultServeMux.Handle("/alerts", r)
	http.DefaultServeMux.Handle("/alertdiff/", r)

	http.DefaultServeMux.Handle("/", rootRouter)
}
