// Copyright 2023 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.

//go:build go1.21

package regtest

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"testing"

	"golang.org/x/telemetry"
	"golang.org/x/telemetry/counter"
	"golang.org/x/telemetry/internal/config"
	icounter "golang.org/x/telemetry/internal/counter"
	it "golang.org/x/telemetry/internal/telemetry"
	"golang.org/x/telemetry/internal/testenv"
)

// programs to run
const (
	progIncCounters = "inccounters"
	prog1           = "prog1"
	prog2           = "prog2"
)

func TestMain(m *testing.M) {
	Main(m, map[string]func() int{
		progIncCounters: func() int {
			counter.Inc("counter")
			counter.Inc("counter:surprise")
			counter.New("gopls/editor:expected").Inc()
			counter.New("gopls/editor:surprise").Inc()
			counter.NewStack("stack/expected", 1).Inc()
			counter.NewStack("stack-surprise", 1).Inc()
			return 0
		},
		prog1: func() int {
			fmt.Println("FuncB")
			return 0
		},
		prog2: func() int {
			fmt.Println("FuncC")
			return 1
		},
	})
}

func TestRunProg(t *testing.T) {
	testenv.MustHaveExec(t)
	telemetryDir := t.TempDir()
	t.Run("prog1", func(t *testing.T) {
		if out, err := RunProg(telemetryDir, prog1); err != nil || !bytes.Contains(out, []byte("FuncB")) || bytes.Contains(out, []byte("FuncC")) {
			t.Errorf("first RunProg = (%s, %v), want FuncB' and succeed", out, err)
		}
	})
	t.Run("prog2", func(t *testing.T) {
		if out, err := RunProg(telemetryDir, prog2); err == nil || bytes.Contains(out, []byte("FuncB")) || !bytes.Contains(out, []byte("FuncC")) {
			t.Errorf("second RunProg = (%s, %v), want 'FuncC' and fail", out, err)
		}
	})
}

func TestE2E_off(t *testing.T) {
	testenv.MustHaveExec(t)

	tests := []struct {
		mode         string // if empty, don't set the mode
		wantLocalDir bool
	}{
		{"", true},
		{"local", true},
		{"on", true},
		{"off", false},
	}

	for _, test := range tests {
		t.Run(fmt.Sprintf("mode=%s", test.mode), func(t *testing.T) {
			telemetryDir := t.TempDir()
			if test.mode != "" {
				if err := it.ModeFilePath(filepath.Join(telemetryDir, "mode")).SetMode(test.mode); err != nil {
					t.Fatalf("SetMode failed: %v", err)
				}
			}
			out, err := RunProg(telemetryDir, progIncCounters)
			if err != nil {
				t.Fatalf("program failed unexpectedly (%v)\n%s", err, out)
			}
			localDir := filepath.Join(telemetryDir, "local")
			_, err = os.Stat(localDir)
			if err != nil && !os.IsNotExist(err) {
				t.Fatalf("os.Stat(%q): unexpected error: %v", localDir, err)
			}
			if gotLocalDir := err == nil; gotLocalDir != test.wantLocalDir {
				t.Errorf("got /local dir: %v, want %v; out:\n%s", gotLocalDir, test.wantLocalDir, string(out))
			}
		})
	}
}

func TestE2E(t *testing.T) {
	testenv.MustHaveExec(t)
	telemetryDir := t.TempDir()

	goVers, progVers, progName := ProgInfo(t)

	out, err := RunProg(telemetryDir, progIncCounters)
	if err != nil {
		t.Fatalf("program failed unexpectedly (%v)\n%s", err, out)
	}

	// TODO: retrieve config through a module proxy so we test internal/configstore code path.
	cfg := &telemetry.UploadConfig{
		GOOS:      []string{runtime.GOOS},
		GOARCH:    []string{runtime.GOARCH},
		GoVersion: []string{goVers},
		Programs: []*telemetry.ProgramConfig{
			{
				Name:     progName,
				Versions: []string{progVers},
				Counters: []telemetry.CounterConfig{
					{Name: "counter", Rate: 1},
					{Name: "gopls/editor:{expected, other}", Rate: 1},
				},
				Stacks: []telemetry.CounterConfig{
					{Name: "stack/expected", Rate: 1, Depth: 1},
				},
			},
		},
	}

	// TODO: check if weekday file exists.

	// TODO: test upload path.
	//     - change the global clock (maybe internal/clock package?)
	//     - start an upload server
	//     - Run(t, telemetryDir, func() int { upload.Run(...) })
	//     - check if the upload server received expected data
	//     - check if the local and upload directories in the expected state

	uploaded, notUploaded, err := parseCounters(cfg, telemetryDir)
	if err != nil {
		t.Fatalf("failed to simulate upload: %v", err)
	}

	wantUpload := map[string]uint64{
		"counter":               1,
		"gopls/editor:expected": 1,
		"stack/expected\n":      1, // prefix of the stack counter name + "\n". see parseCounters.
	}
	testCounterUploadStatus(t, uploaded, wantUpload, false)

	wantNotUpload := map[string]uint64{
		"counter:surprise":      1,
		"gopls/editor:surprise": 1,
		"stack-surprise\n":      1, // prefix of the stack counter name + "\n". see parseCounters.
	}
	testCounterUploadStatus(t, notUploaded, wantNotUpload, true)
}

// testCounterUploadStatus checks if got and want counter maps match.
// If allowUnexpected is true, it checks if got is a superset of want.
func testCounterUploadStatus(t *testing.T, got, want map[string]uint64, allowUnexpected bool) {
	t.Helper()

	seen := got
	if allowUnexpected {
		// filter out unexpected counters from got, for comparison.
		m := make(map[string]uint64, len(want))
		for k, v := range got {
			if _, ok := want[k]; ok {
				m[k] = v
			}
		}
		seen = m
	}
	if !reflect.DeepEqual(seen, want) {
		// TODO(hyangah) implement diff or copy Go project's internal/diff for pretty printing of diff.
		// Or, move internal/regtest to the godev module where we can depend on go-cmp.
		t.Errorf("unmet expectation:\ngot %v\nwant %v", stringify(got), stringify(want))
	}
}

func stringify(a any) string {
	encoded, err := json.MarshalIndent(a, "\t", " ")
	if err != nil {
		return fmt.Sprintf("unmarshallable - %v", err)
	}
	return string(encoded)
}

// parseCounters reads all counter files in the local telemetry directory, and
// returns all observed counters grouped by whether the counter names are included
// in the specified configuration.
// For simplicity in the comparison code, the returned maps represent a stack counter
// with its counter name prefix and "\n". For example, if there are "stackcounter\npkg.F:..."
// and "stackcounter\npkg.G:..", "stackcounter\n" will hold the sum of those counters.
func parseCounters(uc *telemetry.UploadConfig, telemetryDir string) (uploadable, notUploadable map[string]uint64, _ error) {
	cfg := config.NewConfig(uc)
	localDir := filepath.Join(telemetryDir, "local")
	entries, err := os.ReadDir(localDir)
	if err != nil {
		return nil, nil, err
	}
	uploadable, notUploadable = make(map[string]uint64), make(map[string]uint64)
	for _, entry := range entries {
		if entry.IsDir() || filepath.Ext(entry.Name()) != ".count" {
			continue
		}
		data, err := os.ReadFile(filepath.Join(localDir, entry.Name()))
		if err != nil { // ignore unreadable file.
			continue
		}
		// TODO(hyangah): how about exposing "Parse" to public for testing? (i.e. countertest.Parse)?
		parsed, err := icounter.Parse(entry.Name(), data)
		if err != nil { // ignore unparsable file
			continue
		}
		// The following is temporary until the upload package implements the exact same logic.
		// TODO(hyangah): replace with the shared logic between the uploader and the local viewer.
		maybeUploadable := true &&
			cfg.HasGOOS(parsed.Meta["GOOS"]) &&
			cfg.HasGOARCH(parsed.Meta["GOARCH"]) &&
			cfg.HasGoVersion(parsed.Meta["GoVersion"]) &&
			cfg.HasProgram(parsed.Meta["Program"]) &&
			cfg.HasVersion(parsed.Meta["Program"], parsed.Meta["Version"])

		for k, v := range parsed.Count {
			counterPrefix, _, isStackCounter := strings.Cut(k, "\n")
			isUploadable := maybeUploadable
			key := k
			if isStackCounter {
				isUploadable = isUploadable && cfg.HasStack(parsed.Meta["Program"], counterPrefix)
				key = counterPrefix + "\n"
			} else {
				isUploadable = isUploadable && cfg.HasCounter(parsed.Meta["Program"], k)
			}
			if isUploadable {
				uploadable[key] = uploadable[key] + v
			} else {
				notUploadable[key] = notUploadable[key] + v
			}
		}
	}
	return uploadable, notUploadable, nil
}
