// Copyright 2018 The Fuchsia 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 secrets

import (
	"context"
	"crypto/sha256"
	"encoding/json"
	"log"
	"net/http"
	"strconv"
	"strings"

	"go.chromium.org/luci/lucictx"
)

// A mapping of test name to associated secret.
type testSecrets map[string]string

// ServeSecret serves the secret associated to a test, where the request's URL is of the
// form "/<test name>".
func (secrets testSecrets) serveSecret(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	testName := strings.TrimPrefix(r.URL.Path, "/")
	secret, ok := secrets[testName]
	if !ok {
		log.Printf("There is no secret to serve for \"%s\"\n", testName)
		w.WriteHeader(http.StatusNotFound)
		return
	}
	log.Printf("Serving secret for \"%s\"\n", testName)

	// If the secret is a JSON string, strip any garbage that may have been prepended or
	// appended in transit.
	start := strings.Index(secret, "{")
	end := strings.LastIndex(secret, "}")
	if start >= 0 && end >= 0 {
		log.Printf("SHA256 before stripping the secret: %x", sha256.Sum256([]byte(secret)))
		secret = secret[start:end+1]
		log.Printf("SHA256 after stripping the secret: %x", sha256.Sum256([]byte(secret)))
	}

	w.WriteHeader(http.StatusOK)
	w.Write([]byte(secret))
}

// Parses out tests secrets serialized in the LUCI_CONTEXT JSON under the
// "secret_bytes" key.
func getSecrets(ctx context.Context) *testSecrets {
	swarming := lucictx.GetSwarming(ctx)
	if swarming == nil {
		return nil
	}
	secrets := new(testSecrets)
	if err := json.Unmarshal(swarming.SecretBytes, secrets); err != nil {
		log.Fatalf("secret_bytes provided, but unreadable: %v", err)
	}
	return secrets
}

// StartSecretsServer starts a server to serve test secrets at localhost:<|port|>.
func StartSecretsServer(ctx context.Context, port int) {
	secrets := getSecrets(ctx)
	if secrets == nil {
		return
	}

	log.Printf("Setting up secrets server at localhost:%d\n", port)
	s := &http.Server{
		Addr:    ":" + strconv.Itoa(port),
		Handler: http.HandlerFunc(secrets.serveSecret),
	}

	go func() {
		if err := s.ListenAndServe(); err != nil {
			log.Print(err)
		}
	}()

	go func() {
		select {
		case <-ctx.Done():
			log.Printf("Shutting down secrets server at localhost:%d\n", port)
			if err := s.Shutdown(context.Background()); err != nil {
				log.Print(err)
			}
		default:
		}
	}()
}
