// Copyright 2019 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 runtime_test

import (
	"bytes"
	"encoding/binary"
	"errors"
	"internal/testenv"
	"os/exec"
	"reflect"
	"runtime"
	"testing"
	"time"
)

func TestFakeTime(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("faketime not supported on windows")
	}

	// Faketime is advanced in checkdead. External linking brings in cgo,
	// causing checkdead not working.
	testenv.MustInternalLink(t, false)

	t.Parallel()

	exe, err := buildTestProg(t, "testfaketime", "-tags=faketime")
	if err != nil {
		t.Fatal(err)
	}

	var stdout, stderr bytes.Buffer
	cmd := exec.Command(exe)
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	err = testenv.CleanCmdEnv(cmd).Run()
	if err != nil {
		t.Fatalf("exit status: %v\n%s", err, stderr.String())
	}

	t.Logf("raw stdout: %q", stdout.String())
	t.Logf("raw stderr: %q", stderr.String())

	f1, err1 := parseFakeTime(stdout.Bytes())
	if err1 != nil {
		t.Fatal(err1)
	}
	f2, err2 := parseFakeTime(stderr.Bytes())
	if err2 != nil {
		t.Fatal(err2)
	}

	const time0 = 1257894000000000000
	got := [][]fakeTimeFrame{f1, f2}
	var want = [][]fakeTimeFrame{{
		{time0 + 1, "line 2\n"},
		{time0 + 1, "line 3\n"},
		{time0 + 1e9, "line 5\n"},
		{time0 + 1e9, "2009-11-10T23:00:01Z"},
	}, {
		{time0, "line 1\n"},
		{time0 + 2, "line 4\n"},
	}}
	if !reflect.DeepEqual(want, got) {
		t.Fatalf("want %v, got %v", want, got)
	}
}

type fakeTimeFrame struct {
	time uint64
	data string
}

func parseFakeTime(x []byte) ([]fakeTimeFrame, error) {
	var frames []fakeTimeFrame
	for len(x) != 0 {
		if len(x) < 4+8+4 {
			return nil, errors.New("truncated header")
		}
		const magic = "\x00\x00PB"
		if string(x[:len(magic)]) != magic {
			return nil, errors.New("bad magic")
		}
		x = x[len(magic):]
		time := binary.BigEndian.Uint64(x)
		x = x[8:]
		dlen := binary.BigEndian.Uint32(x)
		x = x[4:]
		data := string(x[:dlen])
		x = x[dlen:]
		frames = append(frames, fakeTimeFrame{time, data})
	}
	return frames, nil
}

func TestTimeTimerType(t *testing.T) {
	// runtime.timeTimer (exported for testing as TimeTimer)
	// must have time.Timer and time.Ticker as a prefix
	// (meaning those two must have the same layout).
	runtimeTimeTimer := reflect.TypeOf(runtime.TimeTimer{})

	check := func(name string, typ reflect.Type) {
		n1 := runtimeTimeTimer.NumField()
		n2 := typ.NumField()
		if n1 != n2+1 {
			t.Errorf("runtime.TimeTimer has %d fields, want %d (%s has %d fields)", n1, n2+1, name, n2)
			return
		}
		for i := 0; i < n2; i++ {
			f1 := runtimeTimeTimer.Field(i)
			f2 := typ.Field(i)
			t1 := f1.Type
			t2 := f2.Type
			if t1 != t2 && !(t1.Kind() == reflect.UnsafePointer && t2.Kind() == reflect.Chan) {
				t.Errorf("runtime.Timer field %s %v incompatible with %s field %s %v", f1.Name, t1, name, f2.Name, t2)
			}
			if f1.Offset != f2.Offset {
				t.Errorf("runtime.Timer field %s offset %d incompatible with %s field %s offset %d", f1.Name, f1.Offset, name, f2.Name, f2.Offset)
			}
		}
	}

	check("time.Timer", reflect.TypeOf(time.Timer{}))
	check("time.Ticker", reflect.TypeOf(time.Ticker{}))
}
