// Copyright 2015 The Vanadium 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 (
	"bytes"
	"os/exec"
	"path/filepath"
	"reflect"
	"runtime"
	"sort"
	"strings"
	"sync"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/x/lib/cmdline"
	"v.io/x/ref/services/ben"
	"v.io/x/ref/test"
)

func TestGo(t *testing.T) {
	// go test -bench . testdata_test.go
	goTestOutput := runGoTest(t)
	ctx, shutdown := test.V23Init()
	defer shutdown()

	// Start an archival server
	var archiver archiver
	_, server, err := v23.WithNewServer(ctx, "", &archiver, security.AllowEveryone())
	if err != nil {
		t.Fatal(err)
	}

	// Pipe goTestOutput through the "benup" command
	env := cmdline.EnvFromOS()
	env.Stdin = bytes.NewBufferString(goTestOutput)
	out := bytes.NewBuffer(nil)
	env.Stdout = out
	flagArchiver = server.Status().Endpoints[0].Name()
	if err := runUpload(ctx, env, nil); err != nil {
		t.Fatal(err)
	}
	gotS, gotC, gotR := archiver.lastCall()
	// Some sanity checks on the Scenario
	if got, want := gotS.Cpu.Architecture, runtime.GOARCH; got != want {
		t.Errorf("Got %q, want %q", got, want)
	}
	if got, want := gotS.Os.Name, runtime.GOOS; got != want {
		t.Errorf("Got %q, want %q", got, want)
	}
	// And the state of the code
	if len(gotC) == 0 {
		t.Errorf("SourceCode not detected?")
	}
	// All the runs
	// Since goTestOutput was generated by running "go test" directly on a
	// file, the "package name" is set to "command-line-arguments" (by the
	// "go" tool).
	const (
		bmGood       = "command-line-arguments.BenchmarkGood"
		bmThroughput = "command-line-arguments.BenchmarkThroughput"
		bmAllocs     = "command-line-arguments.BenchmarkAllocs"
		bmAll        = "command-line-arguments.BenchmarkAllMetrics"
	)
	var gotNames []string
	for _, run := range gotR {
		gotNames = append(gotNames, run.Name)
		// Some fields should be set for all benchmarks
		if run.Iterations == 0 {
			t.Errorf("Got 0 iterations for %q", run.Name)
		}
		if run.NanoSecsPerOp == 0 {
			t.Errorf("Got 0 NanoSecsPerOp for %q", run.Name)
		}
		if run.Parallelism == 0 {
			t.Errorf("Got 0 parallelism for %q", run.Name)
		}
		switch run.Name {
		case bmGood:
			// No other metrics set
		case bmThroughput:
			if run.MegaBytesPerSec == 0 {
				t.Errorf("Got 0 MegaBytesPerSec for %q", run.Name)
			}
		case bmAllocs:
			if run.AllocsPerOp == 0 {
				t.Errorf("Got 0 AllocsPerOp for %q", run.Name)
			}
			if run.AllocedBytesPerOp == 0 {
				t.Errorf("Got 0 AllocedBytesPerOp for %q", run.Name)
			}
		case bmAll:
			if run.MegaBytesPerSec == 0 {
				t.Errorf("Got 0 MegaBytesPerSec for %q", run.Name)
			}
			if run.AllocsPerOp == 0 {
				t.Errorf("Got 0 AllocsPerOp for %q", run.Name)
			}
			if run.AllocedBytesPerOp == 0 {
				t.Errorf("Got 0 AllocedBytesPerOp for %q", run.Name)
			}
		}
	}
	sort.Strings(gotNames)
	if got, want := gotNames, []string{bmAll, bmAllocs, bmGood, bmThroughput}; !reflect.DeepEqual(got, want) {
		t.Errorf("Got %v, want %v", got, want)
	}
	// And benup output should said that it uploaded 4 benchmarks.
	if want := "Uploaded 4 benchmark(s)"; !strings.Contains(out.String(), want) {
		t.Errorf("Did not find %q in benup output:\n%v", want, out.String())
	}
	if want := "someprotocol://someurl"; !strings.Contains(out.String(), want) {
		t.Errorf("Did not find %q in benup output:\n%v", want, out.String())
	}
}

func TestNoBenchmarks(t *testing.T) {
	// When the input does not contain any results, no RPCs will be send.
	tests := []string{
		"",
		"There is nothing here",
		`
BENDROIDOS_VERSION="Foo bar baz"
Gotcha!`,
	}
	ctx, shutdown := test.V23Init()
	defer shutdown()
	env := cmdline.EnvFromOS()
	for idx, test := range tests {
		env.Stdin = bytes.NewBufferString(test)
		out := bytes.NewBuffer(nil)
		env.Stdout = out
		if err := runUpload(ctx, env, nil); err != nil {
			t.Errorf("%v -- with input #%d %q", err, idx, test)
		}
		if want := "No benchmarks found to upload"; !strings.Contains(out.String(), want) {
			t.Errorf("Did not find %q in output for input #%d (output = %q)", want, idx, out.String())
		}
	}
}

func TestDetectScenario(t *testing.T) {
	scn := detectScenario()
	testAllFieldsSet(t, scn.Cpu)
	testAllFieldsSet(t, scn.Os)
}

func runGoTest(t *testing.T) string {
	// Generates the output of "go test" on testdata_test.go
	_, file, _, ok := runtime.Caller(0)
	if !ok {
		t.Fatalf("failed to extract filename of current source file")
	}
	gobin, err := exec.LookPath("go")
	if err != nil {
		t.Fatalf("go compiler not found in PATH: %v", err)
	}
	versionBytes, err := exec.Command(gobin, "version").CombinedOutput()
	if err != nil {
		t.Fatalf("%v version failed: %v (%s)", gobin, err, versionBytes)
	}
	t.Logf("Go compiler: %s", versionBytes)
	cmd := exec.Command(gobin, "test", "-v", "-bench", ".", filepath.Join(filepath.Dir(file), "testdata_test.go"))
	output, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("%v failed: %v (%s)", cmd.Args, err, output)
	}
	return string(output)
}

type archiver struct {
	mu   sync.Mutex
	scn  ben.Scenario
	code string
	runs []ben.Run
}

func (a *archiver) Archive(ctx *context.T, call rpc.ServerCall, scenario ben.Scenario, code string, runs []ben.Run) (string, error) {
	a.mu.Lock()
	a.scn = scenario
	a.code = code
	a.runs = runs
	a.mu.Unlock()
	return "someprotocol://someurl", nil
}

func (a *archiver) lastCall() (ben.Scenario, string, []ben.Run) {
	a.mu.Lock()
	scn, code, runs := a.scn, a.code, a.runs
	a.scn = ben.Scenario{}
	a.code = ""
	a.runs = nil
	a.mu.Unlock()
	return scn, code, runs
}

func testAllFieldsSet(t *testing.T, value interface{}) {
	rv := reflect.ValueOf(value)
	for i := 0; i < rv.NumField(); i++ {
		f := rv.Field(i)
		v := f.Interface()
		z := reflect.Zero(f.Type()).Interface()
		if reflect.DeepEqual(v, z) {
			t.Errorf("%s not set", rv.Type().Field(i).Name)
		}
	}
}
