// Copyright 2023 Google LLC
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package common

import (
	"context"
	"fmt"
	"os"
	"path/filepath"

	"go.skia.org/infra/go/gcs"
	"go.skia.org/infra/go/now"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/task_driver/go/lib/os_steps"
	"go.skia.org/infra/task_driver/go/td"
)

// PerfGCSBucketName is the name of the perf.skia.org GCS bucket.
const PerfGCSBucketName = "skia-perf"

// The name of the file produced by the C++ test that we should upload to Perf.
const resultsJSON = "results.json"

// BenchmarkInfo contains information about the CI task under which a benchmark is executed.
type BenchmarkInfo struct {
	GitCommit     string
	TaskName      string
	TaskID        string
	ChangelistID  string
	PatchsetOrder string
}

// ComputeBenchmarkTestRunnerCLIFlags returns the command-line flags that should be passed to the
// benchmark test runner.
func ComputeBenchmarkTestRunnerCLIFlags(benchmarkInfo BenchmarkInfo) []string {
	flags := []string{"--gitHash", benchmarkInfo.GitCommit}

	if benchmarkInfo.ChangelistID != "" && benchmarkInfo.PatchsetOrder != "" {
		flags = append(flags,
			"--issue",
			benchmarkInfo.ChangelistID,
			"--patchset",
			benchmarkInfo.PatchsetOrder)
	}

	flags = append(flags,
		"--links",
		"task",
		"https://task-scheduler.skia.org/task/"+benchmarkInfo.TaskID)
	if benchmarkInfo.ChangelistID != "" && benchmarkInfo.PatchsetOrder != "" {
		flags = append(flags,
			"changelist",
			fmt.Sprintf("https://skia-review.googlesource.com/c/skia/+/%s/%s", benchmarkInfo.ChangelistID, benchmarkInfo.PatchsetOrder))
	}

	return flags
}

func UploadToPerf(ctx context.Context, gcsClient gcs.GCSClient, benchmarkInfo BenchmarkInfo, outputsZIPOrDir string) error {
	// Fail loudly if the outputs ZIP or directory does not exist. All benchmark tests should produce
	// a results.json file.
	fileInfo, err := os.Stat(outputsZIPOrDir)
	if err != nil {
		return skerr.Wrap(err)
	}

	// If the undeclared outputs ZIP file or directory is a ZIP file, extract it.
	outputsDir := ""
	if fileInfo.IsDir() {
		outputsDir = outputsZIPOrDir
	} else {
		var err error
		outputsDir, err = ExtractOutputsZip(ctx, outputsZIPOrDir)
		if err != nil {
			return skerr.Wrap(err)
		}
		defer util.RemoveAll(outputsDir)
	}

	// Get path to the results.json file that we will upload to Perf.
	resultsJSONPath := filepath.Join(outputsDir, resultsJSON)
	fileInfo, err = os_steps.Stat(ctx, resultsJSONPath)
	if err != nil {
		return skerr.Wrapf(err, "while stating %q", resultsJSONPath)
	}
	if fileInfo.IsDir() {
		return skerr.Fmt("file %q is a directory", resultsJSONPath)
	}

	resultsJSONBytes, err := os_steps.ReadFile(ctx, resultsJSONPath)
	if err != nil {
		return skerr.Wrap(err)
	}

	gcsPath := computePerfJSONFileGCSPath(ctx, benchmarkInfo)
	gcsURL := fmt.Sprintf("gs://%s/%s", gcsClient.Bucket(), gcsPath)
	return td.Do(ctx, td.Props(fmt.Sprintf("Upload %s", gcsURL)), func(ctx context.Context) error {
		if err := gcsClient.SetFileContents(ctx, gcsPath, gcs.FILE_WRITE_OPTS_TEXT, resultsJSONBytes); err != nil {
			return skerr.Wrapf(err, "while uploading %q", gcsURL)
		}
		return nil
	})
}

// Based on
// https://skia.googlesource.com/skia/+/5096ed4deb06171700c74273b685713bec0ae597/infra/bots/task_drivers/codesize/codesize.go#504
// and
// https://skia.googlesource.com/skia/+/5096ed4deb06171700c74273b685713bec0ae597/infra/bots/task_drivers/codesize/codesize.go#517.
func computePerfJSONFileGCSPath(ctx context.Context, benchmarkInfo BenchmarkInfo) string {
	timePrefix := now.Now(ctx).UTC().Format("2006/01/02/15") // YYYY/MM/DD/HH.
	// Example: nano-json-v1/2022/01/31/01/033ccea12c0949d0f712471bfcb4ed6daf69aaff/BazelTest-Foo-Bar/results_CkPp9ElAaEXyYWNHpXHU.json.
	return fmt.Sprintf("nano-json-v1/%s/%s/%s/results_%s.json", timePrefix, benchmarkInfo.GitCommit, benchmarkInfo.TaskName, benchmarkInfo.TaskID)
}
