// 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)
	log.Printf("SHA256 of 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:
		}
	}()
}
