// 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
// +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...)
}
