// Copyright 2019 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bufio"
	"bytes"
	"crypto"
	"crypto/hmac"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/binary"
	"encoding/json"
	"encoding/pem"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	neturl "net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"boringssl.googlesource.com/boringssl.git/util/fipstools/acvp/acvptool/acvp"
	"boringssl.googlesource.com/boringssl.git/util/fipstools/acvp/acvptool/subprocess"
)

var (
	dumpRegcap      = flag.Bool("regcap", false, "Print module capabilities JSON to stdout")
	configFilename  = flag.String("config", "config.json", "Location of the configuration JSON file")
	jsonInputFile   = flag.String("json", "", "Location of a vector-set input file")
	uploadInputFile = flag.String("upload", "", "Location of a JSON results file to upload")
	uploadDirectory = flag.String("directory", "", "Path to folder where result files to be uploaded are")
	runFlag         = flag.String("run", "", "Name of primitive to run tests for")
	fetchFlag       = flag.String("fetch", "", "Name of primitive to fetch vectors for")
	expectedOutFlag = flag.String("expected-out", "", "Name of a file to write the expected results to")
	wrapperPath     = flag.String("wrapper", "../../../../build/util/fipstools/acvp/modulewrapper/modulewrapper", "Path to the wrapper binary")
)

type Config struct {
	CertPEMFile        string
	PrivateKeyFile     string
	PrivateKeyDERFile  string
	TOTPSecret         string
	ACVPServer         string
	SessionTokensCache string
	LogFile            string
}

func isCommentLine(line []byte) bool {
	var foundCommentStart bool
	for _, b := range line {
		if !foundCommentStart {
			if b == ' ' || b == '\t' {
				continue
			}
			if b != '/' {
				return false
			}
			foundCommentStart = true
		} else {
			return b == '/'
		}
	}
	return false
}

func jsonFromFile(out any, filename string) error {
	in, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer in.Close()

	scanner := bufio.NewScanner(in)
	var commentsRemoved bytes.Buffer
	for scanner.Scan() {
		if isCommentLine(scanner.Bytes()) {
			continue
		}
		commentsRemoved.Write(scanner.Bytes())
		commentsRemoved.WriteString("\n")
	}
	if err := scanner.Err(); err != nil {
		return err
	}

	decoder := json.NewDecoder(&commentsRemoved)
	decoder.DisallowUnknownFields()
	if err := decoder.Decode(out); err != nil {
		return err
	}
	if decoder.More() {
		return errors.New("trailing garbage found")
	}
	return nil
}

// TOTP implements the time-based one-time password algorithm with the suggested
// granularity of 30 seconds. See https://tools.ietf.org/html/rfc6238 and then
// https://tools.ietf.org/html/rfc4226#section-5.3
func TOTP(secret []byte) string {
	const timeStep = 30
	now := uint64(time.Now().Unix()) / 30
	var nowBuf [8]byte
	binary.BigEndian.PutUint64(nowBuf[:], now)
	mac := hmac.New(sha256.New, secret)
	mac.Write(nowBuf[:])
	digest := mac.Sum(nil)
	value := binary.BigEndian.Uint32(digest[digest[31]&15:])
	value &= 0x7fffffff
	value %= 100000000
	return fmt.Sprintf("%08d", value)
}

type Middle interface {
	Close()
	Config() ([]byte, error)
	Process(algorithm string, vectorSet []byte) (any, error)
}

func loadCachedSessionTokens(server *acvp.Server, cachePath string) error {
	cacheDir, err := os.Open(cachePath)
	if err != nil {
		if os.IsNotExist(err) {
			if err := os.Mkdir(cachePath, 0700); err != nil {
				return fmt.Errorf("Failed to create session token cache directory %q: %s", cachePath, err)
			}
			return nil
		}
		return fmt.Errorf("Failed to open session token cache directory %q: %s", cachePath, err)
	}
	defer cacheDir.Close()
	names, err := cacheDir.Readdirnames(0)
	if err != nil {
		return fmt.Errorf("Failed to list session token cache directory %q: %s", cachePath, err)
	}

	loaded := 0
	for _, name := range names {
		if !strings.HasSuffix(name, ".token") {
			continue
		}
		path := filepath.Join(cachePath, name)
		contents, err := os.ReadFile(path)
		if err != nil {
			return fmt.Errorf("Failed to read session token cache entry %q: %s", path, err)
		}
		urlPath, err := neturl.PathUnescape(name[:len(name)-6])
		if err != nil {
			return fmt.Errorf("Failed to unescape token filename %q: %s", name, err)
		}
		server.PrefixTokens[urlPath] = string(contents)
		loaded++
	}

	log.Printf("Loaded %d cached tokens", loaded)
	return nil
}

func trimLeadingSlash(s string) string {
	if strings.HasPrefix(s, "/") {
		return s[1:]
	}
	return s
}

// looksLikeVectorSetHeader returns true iff element looks like it's a
// vectorSetHeader, not a test. Some ACVP files contain a header as the first
// element that should be duplicated into the response, and some don't. If the
// element contains a "url" field, or if it's missing an "algorithm" field,
// then we guess that it's a header.
func looksLikeVectorSetHeader(element json.RawMessage) bool {
	var headerFields struct {
		URL       string `json:"url"`
		Algorithm string `json:"algorithm"`
	}
	if err := json.Unmarshal(element, &headerFields); err != nil {
		return false
	}
	return len(headerFields.URL) > 0 || len(headerFields.Algorithm) == 0
}

// processFile reads a file containing vector sets, at least in the format
// preferred by our lab, and writes the results to stdout.
func processFile(filename string, supportedAlgos []map[string]any, middle Middle) error {
	jsonBytes, err := os.ReadFile(filename)
	if err != nil {
		return err
	}

	var elements []json.RawMessage
	if err := json.Unmarshal(jsonBytes, &elements); err != nil {
		return err
	}

	// There must be at least one element in the file.
	if len(elements) < 1 {
		return errors.New("JSON input is empty")
	}

	var header json.RawMessage
	if looksLikeVectorSetHeader(elements[0]) {
		header, elements = elements[0], elements[1:]
		if len(elements) == 0 {
			return errors.New("JSON input is empty")
		}
	}

	// Build a map of which algorithms our Middle supports.
	algos := make(map[string]struct{})
	for _, supportedAlgo := range supportedAlgos {
		algoInterface, ok := supportedAlgo["algorithm"]
		if !ok {
			continue
		}
		algo, ok := algoInterface.(string)
		if !ok {
			continue
		}
		algos[algo] = struct{}{}
	}

	var result bytes.Buffer
	result.WriteString("[")

	if header != nil {
		headerBytes, err := json.MarshalIndent(header, "", "    ")
		if err != nil {
			return err
		}
		result.Write(headerBytes)
		result.WriteString(",")
	}

	for i, element := range elements {
		var commonFields struct {
			Algo string `json:"algorithm"`
			ID   uint64 `json:"vsId"`
		}
		if err := json.Unmarshal(element, &commonFields); err != nil {
			return fmt.Errorf("failed to extract common fields from vector set #%d", i+1)
		}

		algo := commonFields.Algo
		if _, ok := algos[algo]; !ok {
			return fmt.Errorf("vector set #%d contains unsupported algorithm %q", i+1, algo)
		}

		replyGroups, err := middle.Process(algo, element)
		if err != nil {
			return fmt.Errorf("while processing vector set #%d: %s", i+1, err)
		}

		group := map[string]any{
			"vsId":       commonFields.ID,
			"testGroups": replyGroups,
			"algorithm":  algo,
		}
		replyBytes, err := json.MarshalIndent(group, "", "    ")
		if err != nil {
			return err
		}

		if i != 0 {
			result.WriteString(",")
		}
		result.Write(replyBytes)
	}

	result.WriteString("]\n")
	os.Stdout.Write(result.Bytes())

	return nil
}

// getVectorsWithRetry fetches the given url from the server and parses it as a
// set of vectors. Any server requested retry is handled.
func getVectorsWithRetry(server *acvp.Server, url string) (out acvp.Vectors, vectorsBytes []byte, err error) {
	for {
		if vectorsBytes, err = server.GetBytes(url); err != nil {
			return out, nil, err
		}

		var vectors acvp.Vectors
		if err := json.Unmarshal(vectorsBytes, &vectors); err != nil {
			return out, nil, err
		}

		retry := vectors.Retry
		if retry == 0 {
			return vectors, vectorsBytes, nil
		}

		log.Printf("Server requested %d seconds delay", retry)
		if retry > 10 {
			retry = 10
		}
		time.Sleep(time.Duration(retry) * time.Second)
	}
}

func uploadResult(server *acvp.Server, setURL string, resultData []byte) error {
	resultSize := uint64(len(resultData)) + 32 /* for framing overhead */
	if server.SizeLimit == 0 || resultSize < server.SizeLimit {
		log.Printf("Result size %d bytes", resultSize)
		return server.Post(nil, trimLeadingSlash(setURL)+"/results", resultData)
	}

	// The NIST ACVP server no longer requires the large-upload process,
	// suggesting that this may no longer be needed.
	log.Printf("Result is %d bytes, too much given server limit of %d bytes. Using large-upload process.", resultSize, server.SizeLimit)
	largeRequestBytes, err := json.Marshal(acvp.LargeUploadRequest{
		Size: resultSize,
		URL:  setURL,
	})
	if err != nil {
		return errors.New("failed to marshal large-upload request: " + err.Error())
	}

	var largeResponse acvp.LargeUploadResponse
	if err := server.Post(&largeResponse, "/large", largeRequestBytes); err != nil {
		return errors.New("failed to request large-upload endpoint: " + err.Error())
	}

	log.Printf("Directed to large-upload endpoint at %q", largeResponse.URL)
	req, err := http.NewRequest("POST", largeResponse.URL, bytes.NewBuffer(resultData))
	if err != nil {
		return errors.New("failed to create POST request: " + err.Error())
	}
	token := largeResponse.AccessToken
	if len(token) == 0 {
		token = server.AccessToken
	}
	req.Header.Add("Authorization", "Bearer "+token)
	req.Header.Add("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return errors.New("failed writing large upload: " + err.Error())
	}
	resp.Body.Close()
	if resp.StatusCode != 200 {
		return fmt.Errorf("large upload resulted in status code %d", resp.StatusCode)
	}

	return nil
}

func connect(config *Config, sessionTokensCacheDir string) (*acvp.Server, error) {
	if len(config.TOTPSecret) == 0 {
		return nil, errors.New("config file missing TOTPSecret")
	}
	totpSecret, err := base64.StdEncoding.DecodeString(config.TOTPSecret)
	if err != nil {
		return nil, fmt.Errorf("failed to base64-decode TOTP secret from config file: %s. (Note that the secret _itself_ should be in the config, not the name of a file that contains it.)", err)
	}

	if len(config.CertPEMFile) == 0 {
		return nil, errors.New("config file missing CertPEMFile")
	}
	certPEM, err := os.ReadFile(config.CertPEMFile)
	if err != nil {
		return nil, fmt.Errorf("failed to read certificate from %q: %s", config.CertPEMFile, err)
	}
	block, _ := pem.Decode(certPEM)
	certDER := block.Bytes

	if len(config.PrivateKeyDERFile) == 0 && len(config.PrivateKeyFile) == 0 {
		return nil, errors.New("config file missing PrivateKeyDERFile and PrivateKeyFile")
	}
	if len(config.PrivateKeyDERFile) != 0 && len(config.PrivateKeyFile) != 0 {
		return nil, errors.New("config file has both PrivateKeyDERFile and PrivateKeyFile - can only have one")
	}
	privateKeyFile := config.PrivateKeyDERFile
	if len(config.PrivateKeyFile) > 0 {
		privateKeyFile = config.PrivateKeyFile
	}

	keyBytes, err := os.ReadFile(privateKeyFile)
	if err != nil {
		return nil, fmt.Errorf("failed to read private key from %q: %s", privateKeyFile, err)
	}

	var keyDER []byte
	pemBlock, _ := pem.Decode(keyBytes)
	if pemBlock != nil {
		keyDER = pemBlock.Bytes
	} else {
		keyDER = keyBytes
	}

	var certKey crypto.PrivateKey
	if certKey, err = x509.ParsePKCS1PrivateKey(keyDER); err != nil {
		if certKey, err = x509.ParsePKCS8PrivateKey(keyDER); err != nil {
			return nil, fmt.Errorf("failed to parse private key from %q: %s", privateKeyFile, err)
		}
	}

	serverURL := "https://demo.acvts.nist.gov/"
	if len(config.ACVPServer) > 0 {
		serverURL = config.ACVPServer
	}
	server := acvp.NewServer(serverURL, config.LogFile, [][]byte{certDER}, certKey, func() string {
		return TOTP(totpSecret[:])
	})

	if len(sessionTokensCacheDir) > 0 {
		if err := loadCachedSessionTokens(server, sessionTokensCacheDir); err != nil {
			return nil, err
		}
	}

	return server, nil
}

func getResultsWithRetry(server *acvp.Server, url string) (bool, error) {
FetchResults:
	for {
		var results acvp.SessionResults
		if err := server.Get(&results, trimLeadingSlash(url)+"/results"); err != nil {
			return false, errors.New("failed to fetch session results: " + err.Error())
		}

		if results.Passed {
			log.Print("Test passed")
			return true, nil
		}

		for _, result := range results.Results {
			if result.Status == "incomplete" {
				log.Print("Server hasn't finished processing results. Waiting 10 seconds.")
				time.Sleep(10 * time.Second)
				continue FetchResults
			}
		}

		log.Printf("Server did not accept results: %#v", results)
		return false, nil
	}
}

func getLastDigitDir(path string) (string, error) {
	parts := strings.Split(filepath.Clean(path), string(filepath.Separator))

	for i := len(parts) - 1; i >= 0; i-- {
		part := parts[i]
		if _, err := strconv.Atoi(part); err == nil {
			return part, nil
		}
	}
	return "", errors.New("no directory consisting of only digits found")
}

func uploadResults(results []nistUploadResult, sessionID string, config *Config, sessionTokensCacheDir string) {
	server, err := connect(config, sessionTokensCacheDir)
	if err != nil {
		log.Fatal(err)
	}

	for _, result := range results {
		url := result.URLPath
		payload := result.JSONResult
		log.Printf("Uploading result for %q", url)
		if err := uploadResult(server, url, payload); err != nil {
			log.Fatalf("Failed to upload: %s", err)
		}
	}

	if ok, err := getResultsWithRetry(server, fmt.Sprintf("/acvp/v1/testSessions/%s", sessionID)); err != nil {
		log.Fatal(err)
	} else if !ok {
		os.Exit(1)
	}
}

// Vector Test Result files are JSON formatted with various objects and keys.
// Define structs to read and process the files.
type vectorResult struct {
	Version    string      `json:"acvVersion,omitempty"`
	Algorithm  string      `json:"algorithm,omitempty"`
	ID         int         `json:"vsId,omitempty"`
	// Objects under testGroups can have various keys so use an empty interface.
	Tests []map[string]interface{} `json:"testGroups,omitempty"`
}

func getVectorSetID(jsonData []vectorResult) (int, error) {
	vsId := 0
	for _, item := range jsonData {
		if item.ID > 0 && vsId == 0 {
			vsId = item.ID
		} else if item.ID > 0 && vsId != 0 {
			return 0, errors.New("found multiple vsId values")
		}
	}
	if vsId != 0 {
		return vsId, nil
	}
	return 0, errors.New("could not find vsId")
}

func getVectorResult(jsonData []vectorResult) ([]byte, error) {
	for _, item := range jsonData {
		if item.ID > 0 {
			out, err := json.Marshal(item)
			if err != nil {
				return nil, fmt.Errorf("unable to marshal JSON due to %s", err)
			}
			return out, nil
		}
	}
	return nil, errors.New("could not find vsId necessary to identify vector result")
}

// Results to be uploaded have a specific URL path to POST/PUT to, along with
// the test results.
// Define a struct and store this data for processing.
type nistUploadResult struct {
	URLPath    string
	JSONResult []byte
}

// Uploads a results directory based on the directory name being the session id.
// Non-JSON files are ignored and JSON files are assumed to be test results.
// The vectorSetId is retrieved from the test result file.
func uploadResultsDirectory(directory string, config *Config, sessionTokensCacheDir string) {
	directory = filepath.Clean(directory)
	sessionID, err := getLastDigitDir(directory)
	if err != nil {
		log.Fatal(err)
	}

	var results []nistUploadResult
	// Read directory, identify, and process all files.
	files, err := ioutil.ReadDir(directory)
	if err != nil {
		log.Fatalf("Unable to read directory: %s", err)
	}

	for _, file := range files {
		// Add contents of the result file to results.
		filePath := filepath.Join(directory, file.Name())
		in, err := ioutil.ReadFile(filePath)
		if err != nil {
			log.Fatalf("Cannot open input: %s", err)
		}

		var data []vectorResult
		if err := json.Unmarshal(in, &data); err != nil {
			// Assume file is not JSON. Log and continue to next file.
			log.Printf("Failed to parse %q: %s", filePath, err)
			continue
		}

		vectorSetID, err := getVectorSetID(data)
		if err != nil {
			log.Fatalf("Failed to get VectorSetId: %s", err)
		}
		// uploadResult() uses acvp.Server whose write() function takes the
		// JSON *object* payload and turns it into a JSON *array* adding
		// {"acvVersion":"1.0"} as a top-level object. Since the result file is
		// already in this format, the JSON provided to uploadResult() must be
		// modified to have those aspects removed. In other words, only store only
		// the vector test result JSON object (do not store a JSON array or
		// acvVersion object).
		vectorTestResult, err := getVectorResult(data)
		if err != nil {
			log.Fatalf("Failed to get VectorResult: %s", err)
		}
		requestPath := fmt.Sprintf("/acvp/v1/testSessions/%s/vectorSets/%d", sessionID, vectorSetID)
		newResult := nistUploadResult{URLPath: requestPath, JSONResult: vectorTestResult}
		results = append(results, newResult)
	}

	uploadResults(results, sessionID, config, sessionTokensCacheDir)
}

// vectorSetHeader is the first element in the array of JSON elements that makes
// up the on-disk format for a vector set.
type vectorSetHeader struct {
	URL           string   `json:"url,omitempty"`
	VectorSetURLs []string `json:"vectorSetUrls,omitempty"`
	Time          string   `json:"time,omitempty"`
}

func uploadFromFile(file string, config *Config, sessionTokensCacheDir string) {
	in, err := os.Open(file)
	if err != nil {
		log.Fatalf("Cannot open input: %s", err)
	}
	defer in.Close()

	decoder := json.NewDecoder(in)

	var input []json.RawMessage
	if err := decoder.Decode(&input); err != nil {
		log.Fatalf("Failed to parse input: %s", err)
	}

	if len(input) < 2 {
		log.Fatalf("Input JSON has fewer than two elements")
	}

	var header vectorSetHeader
	if err := json.Unmarshal(input[0], &header); err != nil {
		log.Fatalf("Failed to parse input header: %s", err)
	}

	if numGroups := len(input) - 1; numGroups != len(header.VectorSetURLs) {
		log.Fatalf("have %d URLs from header, but only %d result groups", len(header.VectorSetURLs), numGroups)
	}

	// Process input and header data to nistUploadResult struct to simplify uploads.
	var results []nistUploadResult
	for i, url := range header.VectorSetURLs {
		newResult := nistUploadResult{URLPath: url, JSONResult: input[i+1]}
		results = append(results, newResult)
	}
	sessionID, err := getLastDigitDir(header.URL)
	if err != nil {
		log.Fatalf("Cannot get session id: %s", err)
	}

	uploadResults(results, sessionID, config, sessionTokensCacheDir)
}

func main() {
	flag.Parse()
	// Check for various flags that are exclusive of each other.
	// The flags that are available to upload results depend on the result format and storage.
	// Only one result flag can be used at a time.
	resultFlags := []bool{len(*uploadInputFile) > 0, len(*uploadDirectory) > 0}
	resultFlagCount := 0
	for _, f := range resultFlags {
		if f {
			resultFlagCount++
		}
	}
	if resultFlagCount > 1 {
		log.Fatalf("only one submit result action (-upload, -directory) is allowed at a time")
	} else if resultFlagCount == 1 {
		if len(*jsonInputFile) > 0 {
			log.Fatalf("submit result action (-upload, -directory) cannot be used with -json")
		} else if len(*runFlag) > 0 {
			log.Fatalf("submit result action (-upload, -directory) cannot be used with -run")
		} else if len(*fetchFlag) > 0 {
			log.Fatalf("submit result action (-upload, -directory) cannot be used with -fetch")
		} else if len(*expectedOutFlag) > 0 {
			log.Fatalf("submit result action (-upload, -directory) cannot be used with -expected-out")
		} else if *dumpRegcap {
			log.Fatalf("submit result action (-upload, -directory) cannot be used with -regcap")
		}
	}

	middle, err := subprocess.New(*wrapperPath)
	if err != nil {
		log.Fatalf("failed to initialise middle: %s", err)
	}
	defer middle.Close()

	configBytes, err := middle.Config()
	if err != nil {
		log.Fatalf("failed to get config from middle: %s", err)
	}

	var supportedAlgos []map[string]any
	if err := json.Unmarshal(configBytes, &supportedAlgos); err != nil {
		log.Fatalf("failed to parse configuration from Middle: %s", err)
	}

	if *dumpRegcap {
		nonTestAlgos := make([]map[string]any, 0, len(supportedAlgos))
		for _, algo := range supportedAlgos {
			if value, ok := algo["acvptoolTestOnly"]; ok {
				testOnly, ok := value.(bool)
				if !ok {
					log.Fatalf("modulewrapper config contains acvptoolTestOnly field with non-boolean value %#v", value)
				}
				if testOnly {
					continue
				}
			}
			if value, ok := algo["algorithm"]; ok {
				algorithm, ok := value.(string)
				if ok && algorithm == "acvptool" {
					continue
				}
			}
			nonTestAlgos = append(nonTestAlgos, algo)
		}

		regcap := []map[string]any{
			{"acvVersion": "1.0"},
			{"algorithms": nonTestAlgos},
		}
		regcapBytes, err := json.MarshalIndent(regcap, "", "    ")
		if err != nil {
			log.Fatalf("failed to marshal regcap: %s", err)
		}
		os.Stdout.Write(regcapBytes)
		os.Stdout.WriteString("\n")
		return
	}

	if len(*jsonInputFile) > 0 {
		if err := processFile(*jsonInputFile, supportedAlgos, middle); err != nil {
			log.Fatalf("failed to process input file: %s", err)
		}
		return
	}

	var requestedAlgosFlag string
	// The output file to which expected results are written, if requested.
	var expectedOut *os.File
	// A tee that outputs to both stdout (for vectors) and the file for
	// expected results, if any.
	var fetchOutputTee io.Writer

	if len(*runFlag) > 0 && len(*fetchFlag) > 0 {
		log.Fatalf("cannot specify both -run and -fetch")
	}
	if len(*expectedOutFlag) > 0 && len(*fetchFlag) == 0 {
		log.Fatalf("-expected-out can only be used with -fetch")
	}
	if len(*runFlag) > 0 {
		requestedAlgosFlag = *runFlag
	} else {
		requestedAlgosFlag = *fetchFlag
		if len(*expectedOutFlag) > 0 {
			if expectedOut, err = os.Create(*expectedOutFlag); err != nil {
				log.Fatalf("cannot open %q: %s", *expectedOutFlag, err)
			}
			fetchOutputTee = io.MultiWriter(os.Stdout, expectedOut)
			defer expectedOut.Close()
		} else {
			fetchOutputTee = os.Stdout
		}
	}

	runAlgos := make(map[string]bool)
	if len(requestedAlgosFlag) > 0 {
		for _, substr := range strings.Split(requestedAlgosFlag, ",") {
			runAlgos[substr] = false
		}
	}

	var algorithms []map[string]any
	for _, supportedAlgo := range supportedAlgos {
		algoInterface, ok := supportedAlgo["algorithm"]
		if !ok {
			continue
		}

		algo, ok := algoInterface.(string)
		if !ok {
			continue
		}

		if _, ok := runAlgos[algo]; ok {
			algorithms = append(algorithms, supportedAlgo)
			runAlgos[algo] = true
		}
	}

	for algo, recognised := range runAlgos {
		if !recognised {
			log.Fatalf("requested algorithm %q was not recognised", algo)
		}
	}

	var config Config
	if err := jsonFromFile(&config, *configFilename); err != nil {
		log.Fatalf("Failed to load config file: %s", err)
	}

	var sessionTokensCacheDir string
	if len(config.SessionTokensCache) > 0 {
		sessionTokensCacheDir = config.SessionTokensCache
		if strings.HasPrefix(sessionTokensCacheDir, "~/") {
			home := os.Getenv("HOME")
			if len(home) == 0 {
				log.Fatal("~ used in config file but $HOME not set")
			}
			sessionTokensCacheDir = filepath.Join(home, sessionTokensCacheDir[2:])
		}
	}

	if len(*uploadInputFile) > 0 {
		uploadFromFile(*uploadInputFile, &config, sessionTokensCacheDir)
		return
	}

	if len(*uploadDirectory) > 0 {
		uploadResultsDirectory(*uploadDirectory, &config, sessionTokensCacheDir)
		return
	}

	server, err := connect(&config, sessionTokensCacheDir)
	if err != nil {
		log.Fatal(err)
	}

	if err := server.Login(); err != nil {
		log.Fatalf("failed to login: %s", err)
	}

	if len(requestedAlgosFlag) == 0 {
		if interactiveModeSupported {
			runInteractive(server, config)
		} else {
			log.Fatalf("no arguments given but interactive mode not supported")
		}
		return
	}

	requestBytes, err := json.Marshal(acvp.TestSession{
		IsSample:    true,
		Publishable: false,
		Algorithms:  algorithms,
	})
	if err != nil {
		log.Fatalf("Failed to serialise JSON: %s", err)
	}

	var result acvp.TestSession
	if err := server.Post(&result, "acvp/v1/testSessions", requestBytes); err != nil {
		log.Fatalf("Request to create test session failed: %s", err)
	}

	url := trimLeadingSlash(result.URL)
	log.Printf("Created test session %q", url)
	if token := result.AccessToken; len(token) > 0 {
		server.PrefixTokens[url] = token
		if len(sessionTokensCacheDir) > 0 {
			os.WriteFile(filepath.Join(sessionTokensCacheDir, neturl.PathEscape(url))+".token", []byte(token), 0600)
		}
	}

	log.Printf("Have vector sets %v", result.VectorSetURLs)

	if len(*fetchFlag) > 0 {
		io.WriteString(fetchOutputTee, "[\n")
		json.NewEncoder(fetchOutputTee).Encode(vectorSetHeader{
			URL:           url,
			VectorSetURLs: result.VectorSetURLs,
			Time:          time.Now().Format(time.RFC3339),
		})
	}

	for _, setURL := range result.VectorSetURLs {
		log.Printf("Fetching test vectors %q", setURL)

		vectors, vectorsBytes, err := getVectorsWithRetry(server, trimLeadingSlash(setURL))
		if err != nil {
			log.Fatalf("Failed to fetch vector set %q: %s", setURL, err)
		}

		if len(*fetchFlag) > 0 {
			os.Stdout.WriteString(",\n")
			os.Stdout.Write(vectorsBytes)
		}

		if expectedOut != nil {
			log.Printf("Fetching expected results")

			_, expectedResultsBytes, err := getVectorsWithRetry(server, trimLeadingSlash(setURL)+"/expected")
			if err != nil {
				log.Fatalf("Failed to fetch expected results: %s", err)
			}

			expectedOut.WriteString(",")
			expectedOut.Write(expectedResultsBytes)
		}

		if len(*fetchFlag) > 0 {
			continue
		}

		replyGroups, err := middle.Process(vectors.Algo, vectorsBytes)
		if err != nil {
			log.Printf("Failed: %s", err)
			log.Printf("Deleting test set")
			server.Delete(url)
			os.Exit(1)
		}

		headerBytes, err := json.Marshal(acvp.Vectors{
			ID:   vectors.ID,
			Algo: vectors.Algo,
		})
		if err != nil {
			log.Printf("Failed to marshal result: %s", err)
			log.Printf("Deleting test set")
			server.Delete(url)
			os.Exit(1)
		}

		var resultBuf bytes.Buffer
		resultBuf.Write(headerBytes[:len(headerBytes)-1])
		resultBuf.WriteString(`,"testGroups":`)
		replyBytes, err := json.Marshal(replyGroups)
		if err != nil {
			log.Printf("Failed to marshal result: %s", err)
			log.Printf("Deleting test set")
			server.Delete(url)
			os.Exit(1)
		}
		resultBuf.Write(replyBytes)
		resultBuf.WriteString("}")

		if err := uploadResult(server, setURL, resultBuf.Bytes()); err != nil {
			log.Printf("Deleting test set")
			server.Delete(url)
			log.Fatal(err)
		}
	}

	if len(*fetchFlag) > 0 {
		io.WriteString(fetchOutputTee, "]\n")
		return
	}

	if ok, err := getResultsWithRetry(server, url); err != nil {
		log.Fatal(err)
	} else if !ok {
		os.Exit(1)
	}
}
