// Copyright 2020 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 && (linux || darwin)
// +build go1.16
// +build linux darwin

// Code related to the Build Results API.

package main

import (
	"context"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strings"

	"golang.org/x/build/cmd/coordinator/protos"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	grpcstatus "google.golang.org/grpc/status"
)

type gRPCServer struct {
	// embed an UnimplementedCoordinatorServer to avoid errors when adding new RPCs to the proto.
	*protos.UnimplementedCoordinatorServer

	// dashboardURL is the base URL of the Dashboard service (https://build.golang.org)
	dashboardURL string
}

// ClearResults implements the ClearResults RPC call from the CoordinatorService.
//
// It currently hits the build Dashboard service to clear a result.
// TODO(golang.org/issue/34744) - Change to wipe build status from the Coordinator itself after findWork
// starts using maintner.
func (g *gRPCServer) ClearResults(ctx context.Context, req *protos.ClearResultsRequest) (*protos.ClearResultsResponse, error) {
	key, err := keyFromContext(ctx)
	if err != nil {
		return nil, err
	}
	if req.GetBuilder() == "" || req.GetHash() == "" {
		return nil, grpcstatus.Error(codes.InvalidArgument, "Builder and Hash must be provided")
	}
	if err := g.clearFromDashboard(ctx, req.GetBuilder(), req.GetHash(), key); err != nil {
		return nil, err
	}
	return &protos.ClearResultsResponse{}, nil
}

// clearFromDashboard calls the dashboard API to remove a build.
// TODO(golang.org/issue/34744) - Remove after switching to wiping in the Coordinator.
func (g *gRPCServer) clearFromDashboard(ctx context.Context, builder, hash, key string) error {
	u, err := url.Parse(g.dashboardURL)
	if err != nil {
		log.Printf("gRPCServer.ClearResults: Error parsing dashboardURL %q: %v", g.dashboardURL, err)
		return grpcstatus.Error(codes.Internal, codes.Internal.String())
	}
	u.Path = "/clear-results"
	form := url.Values{
		"builder": {builder},
		"hash":    {hash},
		"key":     {key},
	}
	u.RawQuery = form.Encode() // The Dashboard API does not read the POST body.
	clearReq, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), nil)
	if err != nil {
		log.Printf("gRPCServer.ClearResults: error creating http request: %v", err)
		return grpcstatus.Error(codes.Internal, codes.Internal.String())
	}
	resp, err := http.DefaultClient.Do(clearReq)
	if err != nil {
		log.Printf("gRPCServer.ClearResults: error performing wipe for %q/%q: %v", builder, hash, err)
		return grpcstatus.Error(codes.Internal, codes.Internal.String())
	}
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		log.Printf("gRPCServer.ClearResults: error reading response body for %q/%q: %v", builder, hash, err)
		return grpcstatus.Error(codes.Internal, codes.Internal.String())
	}
	if resp.StatusCode != http.StatusOK {
		log.Printf("gRPCServer.ClearResults: bad status from dashboard: %v (%q)", resp.StatusCode, resp.Status)
		code, ok := statusToCode[resp.StatusCode]
		if !ok {
			code = codes.Internal
		}
		return grpcstatus.Error(code, code.String())
	}
	if len(body) == 0 {
		return nil
	}
	dr := new(dashboardResponse)
	if err := json.Unmarshal(body, dr); err != nil {
		log.Printf("gRPCServer.ClearResults: error parsing response body for %q/%q: %v", builder, hash, err)
		return grpcstatus.Error(codes.Internal, codes.Internal.String())
	}
	if dr.Error == "datastore: concurrent transaction" {
		return grpcstatus.Error(codes.Aborted, dr.Error)
	}
	if dr.Error != "" {
		return grpcstatus.Error(codes.FailedPrecondition, dr.Error)
	}
	return nil
}

// dashboardResponse mimics the dashResponse struct from app/appengine.
// TODO(golang.org/issue/34744) - Remove after switching to wiping in the Coordinator.
type dashboardResponse struct {
	// Error is an error string describing the API response. The dashboard API semantics are to always return a
	// 200, and populate this field with details.
	Error string `json:"Error"`
	// Response a human friendly response from the API. It is not populated for build status clear responses.
	Response string `json:"Response"`
}

// statusToCode maps HTTP status codes to gRPC codes. It purposefully only contains statuses we care to map.
// TODO(golang.org/issue/34744) - Move to shared file or library.
var statusToCode = map[int]codes.Code{
	http.StatusOK:                  codes.OK,
	http.StatusBadRequest:          codes.InvalidArgument,
	http.StatusUnauthorized:        codes.Unauthenticated,
	http.StatusForbidden:           codes.PermissionDenied,
	http.StatusNotFound:            codes.NotFound,
	http.StatusConflict:            codes.Aborted,
	http.StatusGone:                codes.DataLoss,
	http.StatusTooManyRequests:     codes.ResourceExhausted,
	http.StatusInternalServerError: codes.Internal,
	http.StatusNotImplemented:      codes.Unimplemented,
	http.StatusServiceUnavailable:  codes.Unavailable,
	http.StatusGatewayTimeout:      codes.DeadlineExceeded,
}

// keyFromContext loads a builder key from request metadata.
//
// The metadata format is prefixed with "builder " to avoid collisions with OAuth:
//    authorization: builder MYKEY
//
// TODO(golang.org/issue/34744) - Move to shared file or library. This would make a nice UnaryServerInterceptor.
// TODO(golang.org/issue/34744) - Currently allows the Build Dashboard to validate tokens, but we should validate here.
func keyFromContext(ctx context.Context) (string, error) {
	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return "", grpcstatus.Error(codes.Internal, codes.Internal.String())
	}
	auth := md.Get("authorization")
	if len(auth) == 0 || len(auth[0]) < 9 || !strings.HasPrefix(auth[0], "builder ") {
		return "", grpcstatus.Error(codes.Unauthenticated, codes.Unauthenticated.String())
	}
	key := auth[0][8:len(auth[0])]
	return key, nil
}
