package main

import (
	"bytes"
	"context"
	"errors"
	"io"
	"runtime/pprof"
	"strings"
	"testing"
	"time"
)

func TestCPUAndOverlap(t *testing.T) {
	var b bytes.Buffer
	wall, rejected, err := captureCPU(&b, 10*time.Millisecond, 5*time.Millisecond)
	if err != nil || !rejected || wall < 15*time.Millisecond || b.Len() == 0 {
		t.Fatalf("wall=%v rejected=%v bytes=%d err=%v", wall, rejected, b.Len(), err)
	}
}

func TestRejectUnboundedWindow(t *testing.T) {
	for _, busy := range []time.Duration{0, -1, 3 * time.Second} {
		if _, _, err := captureCPU(io.Discard, busy, 0); err == nil {
			t.Fatalf("accepted busy=%s", busy)
		}
	}
}

func TestLabelsRestored(t *testing.T) {
	parent := pprof.WithLabels(context.Background(), pprof.Labels("route", "/parent"))
	pprof.Do(parent, pprof.Labels("route", "/child"), func(ctx context.Context) {
		if value, _ := pprof.Label(ctx, "route"); value != "/child" {
			t.Fatal(value)
		}
	})
	if value, _ := pprof.Label(parent, "route"); value != "/parent" {
		t.Fatal(value)
	}
}

func TestUnknownProfile(t *testing.T) {
	err := writeProfile(t.TempDir(), "not-a-profile")
	if err == nil || !strings.Contains(err.Error(), "unknown profile") {
		t.Fatal(err)
	}
}

var errDisk = errors.New("synthetic disk failure")

type failedWriter struct{}

func (failedWriter) Write([]byte) (int, error) { return 0, errDisk }

func TestSnapshotWriteFailure(t *testing.T) {
	err := pprof.Lookup("goroutine").WriteTo(failedWriter{}, 0)
	if !errors.Is(err, errDisk) {
		t.Fatalf("got %v", err)
	}
}
