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

//go:build go1.16

// Package legacydash holds the serving code for the build dashboard
// (build.golang.org) and its remaining HTTP API endpoints.
//
// It's a code transplant of the previous app/appengine application,
// converted into a package that coordinator can import and use.
// A newer version of the build dashboard is in development in
// the golang.org/x/build/cmd/coordinator/internal/dashboard package.
package legacydash

import (
	"embed"
	"net/http"
	"sort"
	"strings"

	"cloud.google.com/go/datastore"
	"github.com/NYTimes/gziphandler"
	"golang.org/x/build/maintner/maintnerd/apipb"
	"golang.org/x/build/repos"
	"google.golang.org/grpc"
)

var (
	// Datastore client to a GCP project where build results are stored.
	// Typically this is the golang-org GCP project.
	datastoreClient *datastore.Client

	// Maintner client for the maintner service.
	// Typically the one at maintner.golang.org.
	maintnerClient apipb.MaintnerServiceClient

	// The builder master key.
	masterKey string

	// TODO(golang.org/issue/38337): Keep moving away from package scope
	// variables during future refactors.
)

// fakeResults controls whether to make up fake random results. If true, datastore is not used.
const fakeResults = false

// Handler sets a datastore client, maintner client, builder master key and
// GRPC server at the package scope, and returns an HTTP mux for the legacy dashboard.
func Handler(dc *datastore.Client, mc apipb.MaintnerServiceClient, key string, grpcServer *grpc.Server) http.Handler {
	datastoreClient = dc
	maintnerClient = mc
	masterKey = key
	grpcServer = grpcServer

	mux := http.NewServeMux()

	// authenticated handlers
	mux.Handle("/clear-results", hstsGzip(AuthHandler(clearResultsHandler))) // called by coordinator for x/build/cmd/retrybuilds
	mux.Handle("/result", hstsGzip(AuthHandler(resultHandler)))              // called by coordinator after build

	// public handlers
	mux.Handle("/", GRPCHandler(grpcServer, hstsGzip(http.HandlerFunc(uiHandler)))) // enables GRPC server for build.golang.org
	mux.Handle("/log/", hstsGzip(http.HandlerFunc(logHandler)))

	// static handler
	fs := http.FileServer(http.FS(static))
	mux.Handle("/static/", hstsGzip(fs))

	return mux
}

//go:embed static
var static embed.FS

// GRPCHandler creates handler which intercepts requests intended for a GRPC server and directs the calls to the server.
// All other requests are directed toward the passed in handler.
func GRPCHandler(gs *grpc.Server, h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.ProtoMajor == 2 && strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
			gs.ServeHTTP(w, r)
			return
		}
		h.ServeHTTP(w, r)
	})
}

// hstsGzip is short for hstsHandler(GzipHandler(h)).
func hstsGzip(h http.Handler) http.Handler {
	return hstsHandler(gziphandler.GzipHandler(h))
}

// hstsHandler returns a Handler that sets the HSTS header but
// otherwise just wraps h.
func hstsHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Strict-Transport-Security", "max-age=31536000; preload")
		h.ServeHTTP(w, r)
	})
}

// Dashboard describes a unique build dashboard.
//
// (There used to be more than one dashboard, so this is now somewhat
// less important than it once was.)
type Dashboard struct {
	Name     string     // This dashboard's name (always "Go" nowadays)
	Packages []*Package // The project's packages to build
}

// packageWithPath returns the Package in d with the provided importPath,
// or nil if none is found.
func (d *Dashboard) packageWithPath(importPath string) *Package {
	for _, p := range d.Packages {
		if p.Path == importPath {
			return p
		}
	}
	return nil
}

// goDash is the dashboard for the main go repository.
var goDash = &Dashboard{
	Name: "Go",
	Packages: []*Package{
		{Name: "Go"},
	},
}

func init() {
	var add []*Package
	for _, r := range repos.ByGerritProject {
		if !r.ShowOnDashboard() {
			continue
		}
		add = append(add, &Package{
			Name: r.GoGerritProject,
			Path: r.ImportPath,
		})
	}
	sort.Slice(add, func(i, j int) bool {
		return add[i].Name < add[j].Name
	})
	goDash.Packages = append(goDash.Packages, add...)
}
