// Copyright 2022 The Chromium 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 main

import (
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strconv"
	"syscall"
)

const (
	envPortFileBaseName = "port"
)

func main() {
	envDir, envReadyFile := mustGetEnvironmentVariables()

	port, listener := mustGetUnusedNetworkPort()

	beginTestManagementLogic(listener)

	mustPrepareTestEnvironment(envDir, port)

	setupTerminationLogic()

	mustSignalTestsCanBegin(envReadyFile)

	select {} // Block until the termination handler calls os.Exit
}

// mustGetEnvironmentVariables returns two file paths: a directory that can be used to communicate
// between this binary and the test binaries, and the file that needs to be created when this
// binary has finished setting things up. It panics if it cannot read the values from the
// set environment variables.
func mustGetEnvironmentVariables() (string, string) {
	// Read in build paths to the ready and port files.
	envDir := os.Getenv("ENV_DIR")
	if envDir == "" {
		panic("required environment variable ENV_DIR is unset")
	}
	envReadyFile := os.Getenv("ENV_READY_FILE")
	if envReadyFile == "" {
		panic("required environment variable ENV_READY_FILE is unset")
	}
	return envDir, envReadyFile
}

// mustGetUnusedNetworkPort returns a network port chosen by the OS (and assumed to be previously
// unused) and a listener for that port. We choose a non-deterministic port instead of a fixed port
// because multiple tests may be running in parallel.
func mustGetUnusedNetworkPort() (int, net.Listener) {
	// Listen on an unused port chosen by the OS.
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		panic(err)
	}
	port := listener.Addr().(*net.TCPAddr).Port
	fmt.Printf("Environment is ready to go!\nListening on port %d.\n", port)
	return port, listener
}

// beginTestManagementLogic sets up the server endpoints which allow the JS gm() tests to exfiltrate
// their PNG images by means of a POST request.
func beginTestManagementLogic(listener net.Listener) {
	// The contents of this path go to //bazel-testlogs/path/to/test/test.outputs/ and are combined
	// into outputs.zip.
	// e.g. ls bazel-testlogs/modules/canvaskit/hello_world_test_with_env/test.outputs/
	//   test_001
	//   test_002
	//   outputs.zip   # contains test_001 and test_002
	// This environment var is documented in https://bazel.build/reference/test-encyclopedia
	outPath := os.Getenv("TEST_UNDECLARED_OUTPUTS_DIR")
	if outPath == "" {
		panic("output directory was not configured")
	}

	http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
	})

	http.HandleFunc("/report", func(w http.ResponseWriter, r *http.Request) {
		payload, err := readPayload(r)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
		}
		if payload.TestName == "" {
			http.Error(w, "Must specify test name", http.StatusBadRequest)
			return
		}
		// Write the data in the POST to the special Bazel output directory
		fileContents, err := base64.StdEncoding.DecodeString(payload.Base64Data)
		if err != nil {
		    fmt.Printf("Invalid base64 data: %s\n", err.Error())
			http.Error(w, "Invalid base64 data "+err.Error(), http.StatusBadRequest)
			return
		}
		fp := filepath.Join(outPath, payload.TestName)
		// Two newlines here makes the log stick out more.
		fmt.Printf("Writing test data to %s\n\n", fp)
		out, err := os.Create(fp)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			panic(err)
		}
		if _, err := out.Write(fileContents); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			panic(err)
		}

		// Signal to the test that we have written the data to disk. Tests should be sure to wait
		// for this response before signaling they are done to avoid a race condition.
		w.WriteHeader(http.StatusCreated)
		// We are not worried about an XSS reflection attack here on a local server only up
		// when running tests.
		if _, err := fmt.Fprintln(w, "Accepted for test "+payload.TestName); err != nil {
			panic(err)
		}
	})
	go func() {
		serveForever(listener)
	}()
}

type testPayload struct {
	TestName   string `json:"name"`
	Base64Data string `json:"b64_data"`
}

// readPayload reads the body of the given request as JSON and parses it into a testPayload struct.
func readPayload(r *http.Request) (testPayload, error) {
	var payload testPayload
	if r.Body == nil {
		return payload, errors.New("no body received")
	}
	b, err := io.ReadAll(r.Body)
	if err != nil {
		return payload, err
	}
	_ = r.Body.Close()
	if err := json.Unmarshal(b, &payload); err != nil {
		return payload, errors.New("invalid JSON")
	}
	return payload, nil
}

// serveForever serves the given listener and blocks. If it could not start serving, it will panic.
func serveForever(listener net.Listener) {
	// If http.Serve returns, it is an error.
	if err := http.Serve(listener, nil); err != nil {
		panic(fmt.Sprintf("Finished serving due to error: %s\n", err))
	}
}

// mustPrepareTestEnvironment writes any files to the temporary test directory. This is just a file
// that indicates which port the gold tests should make POST requests to. It panics if there are
// any errors.
func mustPrepareTestEnvironment(dirTestsCanRead string, port int) {
	envPortFile := path.Join(dirTestsCanRead, envPortFileBaseName)
	if err := ioutil.WriteFile(envPortFile, []byte(strconv.Itoa(port)), 0644); err != nil {
		panic(err)
	}
}

// setupTerminationLogic creates a handler for SIGTERM which is what test_on_env will send the
// environment when the tests complete. There is currently nothing to do other than exit.
func setupTerminationLogic() {
	c := make(chan os.Signal, 1)
	go func() {
		<-c
		os.Exit(0)
	}()
	signal.Notify(c, syscall.SIGTERM)
}

// mustSignalTestsCanBegin creates the agreed upon ENV_READY_FILE which signals the test binary can
// be executed by Bazel. See test_on_env.bzl for more. It panics if the file cannot be created.
func mustSignalTestsCanBegin(envReadyFile string) {
	if err := ioutil.WriteFile(envReadyFile, []byte{}, 0644); err != nil {
		panic(err)
	}
}
