// Copyright 2021 The Go 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 fuzz

import (
	"context"
	"flag"
	"fmt"
	"io"
	"os"
	"os/signal"
	"reflect"
	"testing"
)

var benchmarkWorkerFlag = flag.Bool("benchmarkworker", false, "")

func TestMain(m *testing.M) {
	flag.Parse()
	if *benchmarkWorkerFlag {
		runBenchmarkWorker()
		return
	}
	os.Exit(m.Run())
}

func BenchmarkWorkerFuzzOverhead(b *testing.B) {
	origEnv := os.Getenv("GODEBUG")
	defer func() { os.Setenv("GODEBUG", origEnv) }()
	os.Setenv("GODEBUG", fmt.Sprintf("%s,fuzzseed=123", origEnv))

	ws := &workerServer{
		fuzzFn:     func(_ CorpusEntry) error { return nil },
		workerComm: workerComm{memMu: make(chan *sharedMem, 1)},
	}

	mem, err := sharedMemTempFile(workerSharedMemSize)
	if err != nil {
		b.Fatalf("failed to create temporary shared memory file: %s", err)
	}
	defer func() {
		if err := mem.Close(); err != nil {
			b.Error(err)
		}
	}()

	initialVal := []interface{}{make([]byte, 32)}
	encodedVals := marshalCorpusFile(initialVal...)
	mem.setValue(encodedVals)

	ws.memMu <- mem

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		ws.m = newMutator()
		mem.setValue(encodedVals)
		mem.header().count = 0

		ws.fuzz(context.Background(), fuzzArgs{Limit: 1})
	}
}

// BenchmarkWorkerPing acts as the coordinator and measures the time it takes
// a worker to respond to N pings. This is a rough measure of our RPC latency.
func BenchmarkWorkerPing(b *testing.B) {
	b.SetParallelism(1)
	w := newWorkerForTest(b)
	for i := 0; i < b.N; i++ {
		if err := w.client.ping(context.Background()); err != nil {
			b.Fatal(err)
		}
	}
}

// BenchmarkWorkerFuzz acts as the coordinator and measures the time it takes
// a worker to mutate a given input and call a trivial fuzz function N times.
func BenchmarkWorkerFuzz(b *testing.B) {
	b.SetParallelism(1)
	w := newWorkerForTest(b)
	entry := CorpusEntry{Values: []interface{}{[]byte(nil)}}
	entry.Data = marshalCorpusFile(entry.Values...)
	for i := int64(0); i < int64(b.N); {
		args := fuzzArgs{
			Limit:   int64(b.N) - i,
			Timeout: workerFuzzDuration,
		}
		_, resp, err := w.client.fuzz(context.Background(), entry, args)
		if err != nil {
			b.Fatal(err)
		}
		if resp.Err != "" {
			b.Fatal(resp.Err)
		}
		if resp.Count == 0 {
			b.Fatal("worker did not make progress")
		}
		i += resp.Count
	}
}

// newWorkerForTest creates and starts a worker process for testing or
// benchmarking. The worker process calls RunFuzzWorker, which responds to
// RPC messages until it's stopped. The process is stopped and cleaned up
// automatically when the test is done.
func newWorkerForTest(tb testing.TB) *worker {
	tb.Helper()
	c, err := newCoordinator(CoordinateFuzzingOpts{
		Types: []reflect.Type{reflect.TypeOf([]byte(nil))},
		Log:   io.Discard,
	})
	if err != nil {
		tb.Fatal(err)
	}
	dir := ""             // same as self
	binPath := os.Args[0] // same as self
	args := append(os.Args[1:], "-benchmarkworker")
	env := os.Environ() // same as self
	w, err := newWorker(c, dir, binPath, args, env)
	if err != nil {
		tb.Fatal(err)
	}
	tb.Cleanup(func() {
		if err := w.cleanup(); err != nil {
			tb.Error(err)
		}
	})
	if err := w.startAndPing(context.Background()); err != nil {
		tb.Fatal(err)
	}
	tb.Cleanup(func() {
		if err := w.stop(); err != nil {
			tb.Error(err)
		}
	})
	return w
}

func runBenchmarkWorker() {
	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
	defer cancel()
	fn := func(CorpusEntry) error { return nil }
	if err := RunFuzzWorker(ctx, fn); err != nil && err != ctx.Err() {
		panic(err)
	}
}
