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

package misc

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/telemetry/counter"
	"golang.org/x/telemetry/counter/countertest"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/protocol/command"
	"golang.org/x/tools/gopls/internal/server"
	. "golang.org/x/tools/gopls/internal/test/integration"
)

// Test prompt file in old and new formats are handled as expected.
func TestTelemetryPrompt_PromptFile(t *testing.T) {
	const src = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {}
`

	defaultTelemetryStartTime := "1714521600" // 2024-05-01
	defaultToken := "7"
	samplesPerMille := "500"

	testCases := []struct {
		name, in, want string
		wantPrompt     bool
	}{
		{
			name:       "empty",
			in:         "",
			want:       "failed 1 1714521600 7",
			wantPrompt: true,
		},
		{
			name:       "v0.15-format/invalid",
			in:         "pending",
			want:       "failed 1 1714521600 7",
			wantPrompt: true,
		},
		{
			name:       "v0.15-format/pPending",
			in:         "pending 1",
			want:       "failed 2 1714521600 7",
			wantPrompt: true,
		},
		{
			name:       "v0.15-format/pPending",
			in:         "failed 1",
			want:       "failed 2 1714521600 7",
			wantPrompt: true,
		},
		{
			name: "v0.15-format/pYes",
			in:   "yes 1",
			want: "yes 1", // untouched since short-circuited
		},
		{
			name: "v0.16-format/pNotReady",
			in:   "- 0 1714521600 1000",
			want: "- 0 1714521600 1000",
		},
		{
			name:       "v0.16-format/pPending",
			in:         "pending 1 1714521600 1",
			want:       "failed 2 1714521600 1",
			wantPrompt: true,
		},
		{
			name:       "v0.16-format/pFailed",
			in:         "failed 2 1714521600 1",
			want:       "failed 3 1714521600 1",
			wantPrompt: true,
		},
		{
			name:       "v0.16-format/invalid",
			in:         "xxx 0 12345 678",
			want:       "failed 1 1714521600 7",
			wantPrompt: true,
		},
		{
			name: "v0.16-format/extra",
			in:   "- 0 1714521600 1000 7777 xxx",
			want: "- 0 1714521600 1000", // drop extra
		},
	}
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			modeFile := filepath.Join(t.TempDir(), "mode")
			goplsConfigDir := t.TempDir()
			promptDir := filepath.Join(goplsConfigDir, "prompt")
			promptFile := filepath.Join(promptDir, "telemetry")

			if err := os.MkdirAll(promptDir, 0777); err != nil {
				t.Fatal(err)
			}
			if err := os.WriteFile(promptFile, []byte(tc.in), 0666); err != nil {
				t.Fatal(err)
			}
			WithOptions(
				Modes(Default), // no need to run this in all modes
				EnvVars{
					server.GoplsConfigDirEnvvar:                  goplsConfigDir,
					server.FakeTelemetryModefileEnvvar:           modeFile,
					server.GoTelemetryGoplsClientStartTimeEnvvar: defaultTelemetryStartTime,
					server.GoTelemetryGoplsClientTokenEnvvar:     defaultToken,
					server.FakeSamplesPerMille:                   samplesPerMille,
				},
				Settings{
					"telemetryPrompt": true,
				},
			).Run(t, src, func(t *testing.T, env *Env) {
				expectation := ShownMessageRequest(".*Would you like to enable Go telemetry?")
				if !tc.wantPrompt {
					expectation = Not(expectation)
				}
				env.OnceMet(
					CompletedWork(server.TelemetryPromptWorkTitle, 1, true),
					expectation,
				)
				if got, err := os.ReadFile(promptFile); err != nil || string(got) != tc.want {
					t.Fatalf("(%q) -> (%q, %v), want %q", tc.in, got, err, tc.want)
				}
			})
		})
	}
}

// Test that gopls prompts for telemetry only when it is supposed to.
func TestTelemetryPrompt_Conditions_Mode(t *testing.T) {
	const src = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {
}
`

	for _, enabled := range []bool{true, false} {
		t.Run(fmt.Sprintf("telemetryPrompt=%v", enabled), func(t *testing.T) {
			for _, initialMode := range []string{"", "local", "off", "on"} {
				t.Run(fmt.Sprintf("initial_mode=%s", initialMode), func(t *testing.T) {
					modeFile := filepath.Join(t.TempDir(), "mode")
					if initialMode != "" {
						if err := os.WriteFile(modeFile, []byte(initialMode), 0666); err != nil {
							t.Fatal(err)
						}
					}
					telemetryStartTime := time.Now().Add(-8 * 24 * time.Hour) // telemetry started a while ago
					WithOptions(
						Modes(Default), // no need to run this in all modes
						EnvVars{
							server.GoplsConfigDirEnvvar:                  t.TempDir(),
							server.FakeTelemetryModefileEnvvar:           modeFile,
							server.GoTelemetryGoplsClientStartTimeEnvvar: strconv.FormatInt(telemetryStartTime.Unix(), 10),
							server.GoTelemetryGoplsClientTokenEnvvar:     "1", // always sample because samplingPerMille >= 1.
						},
						Settings{
							"telemetryPrompt": enabled,
						},
					).Run(t, src, func(t *testing.T, env *Env) {
						wantPrompt := enabled && (initialMode == "" || initialMode == "local")
						expectation := ShownMessageRequest(".*Would you like to enable Go telemetry?")
						if !wantPrompt {
							expectation = Not(expectation)
						}
						env.OnceMet(
							CompletedWork(server.TelemetryPromptWorkTitle, 1, true),
							expectation,
						)
					})
				})
			}
		})
	}
}

// Test that gopls prompts for telemetry only after instrumenting for a while, and
// when the token is within the range for sample.
func TestTelemetryPrompt_Conditions_StartTimeAndSamplingToken(t *testing.T) {
	const src = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {
}
`
	day := 24 * time.Hour
	samplesPerMille := 50
	for _, token := range []int{1, samplesPerMille, samplesPerMille + 1} {
		wantSampled := token <= samplesPerMille
		t.Run(fmt.Sprintf("to_sample=%t/tokens=%d", wantSampled, token), func(t *testing.T) {
			for _, elapsed := range []time.Duration{8 * day, 1 * day, 0} {
				telemetryStartTimeOrEmpty := ""
				if elapsed > 0 {
					telemetryStartTimeOrEmpty = strconv.FormatInt(time.Now().Add(-elapsed).Unix(), 10)
				}
				t.Run(fmt.Sprintf("elapsed=%s", elapsed), func(t *testing.T) {
					modeFile := filepath.Join(t.TempDir(), "mode")
					WithOptions(
						Modes(Default), // no need to run this in all modes
						EnvVars{
							server.GoplsConfigDirEnvvar:                  t.TempDir(),
							server.FakeTelemetryModefileEnvvar:           modeFile,
							server.GoTelemetryGoplsClientStartTimeEnvvar: telemetryStartTimeOrEmpty,
							server.GoTelemetryGoplsClientTokenEnvvar:     strconv.Itoa(token),
							server.FakeSamplesPerMille:                   strconv.Itoa(samplesPerMille), // want token ∈ [1, 50] is always sampled.
						},
						Settings{
							"telemetryPrompt": true,
						},
					).Run(t, src, func(t *testing.T, env *Env) {
						wantPrompt := wantSampled && elapsed > 7*day
						expectation := ShownMessageRequest(".*Would you like to enable Go telemetry?")
						if !wantPrompt {
							expectation = Not(expectation)
						}
						env.OnceMet(
							CompletedWork(server.TelemetryPromptWorkTitle, 1, true),
							expectation,
						)
					})
				})
			}
		})
	}
}

// Test that responding to the telemetry prompt results in the expected state.
func TestTelemetryPrompt_Response(t *testing.T) {
	if !countertest.SupportedPlatform {
		t.Skip("requires counter support")
	}

	const src = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {
}
`

	var (
		acceptanceCounter = "gopls/telemetryprompt/accepted"
		declinedCounter   = "gopls/telemetryprompt/declined"
		attempt1Counter   = "gopls/telemetryprompt/attempts:1"
		allCounters       = []string{acceptanceCounter, declinedCounter, attempt1Counter}
	)

	// We must increment counters in order for the initial reads below to
	// succeed.
	//
	// TODO(rfindley): ReadCounter should simply return 0 for uninitialized
	// counters.
	for _, name := range allCounters {
		counter.New(name).Inc()
	}

	readCounts := func(t *testing.T) map[string]uint64 {
		t.Helper()
		counts := make(map[string]uint64)
		for _, name := range allCounters {
			count, err := countertest.ReadCounter(counter.New(name))
			if err != nil {
				t.Fatalf("ReadCounter(%q) failed: %v", name, err)
			}
			counts[name] = count
		}
		return counts
	}

	tests := []struct {
		name       string // subtest name
		response   string // response to choose for the telemetry dialog
		wantMode   string // resulting telemetry mode
		wantMsg    string // substring contained in the follow-up popup (if empty, no popup is expected)
		wantInc    uint64 // expected 'prompt accepted' counter increment
		wantCounts map[string]uint64
	}{
		{"yes", server.TelemetryYes, "on", "uploading is now enabled", 1, map[string]uint64{
			acceptanceCounter: 1,
			declinedCounter:   0,
			attempt1Counter:   1,
		}},
		{"no", server.TelemetryNo, "", "", 0, map[string]uint64{
			acceptanceCounter: 0,
			declinedCounter:   1,
			attempt1Counter:   1,
		}},
		{"empty", "", "", "", 0, map[string]uint64{
			acceptanceCounter: 0,
			declinedCounter:   0,
			attempt1Counter:   1,
		}},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			initialCounts := readCounts(t)
			modeFile := filepath.Join(t.TempDir(), "mode")
			telemetryStartTime := time.Now().Add(-8 * 24 * time.Hour)
			msgRE := regexp.MustCompile(".*Would you like to enable Go telemetry?")
			respond := func(m *protocol.ShowMessageRequestParams) (*protocol.MessageActionItem, error) {
				if msgRE.MatchString(m.Message) {
					for _, item := range m.Actions {
						if item.Title == test.response {
							return &item, nil
						}
					}
					if test.response != "" {
						t.Errorf("action item %q not found", test.response)
					}
				}
				return nil, nil
			}
			WithOptions(
				Modes(Default), // no need to run this in all modes
				EnvVars{
					server.GoplsConfigDirEnvvar:                  t.TempDir(),
					server.FakeTelemetryModefileEnvvar:           modeFile,
					server.GoTelemetryGoplsClientStartTimeEnvvar: strconv.FormatInt(telemetryStartTime.Unix(), 10),
					server.GoTelemetryGoplsClientTokenEnvvar:     "1", // always sample because samplingPerMille >= 1.
				},
				Settings{
					"telemetryPrompt": true,
				},
				MessageResponder(respond),
			).Run(t, src, func(t *testing.T, env *Env) {
				var postConditions []Expectation
				if test.wantMsg != "" {
					postConditions = append(postConditions, ShownMessage(test.wantMsg))
				}
				env.OnceMet(
					CompletedWork(server.TelemetryPromptWorkTitle, 1, true),
					postConditions...,
				)
				gotMode := ""
				if contents, err := os.ReadFile(modeFile); err == nil {
					gotMode = string(contents)
				} else if !os.IsNotExist(err) {
					t.Fatal(err)
				}
				if gotMode != test.wantMode {
					t.Errorf("after prompt, mode=%s, want %s", gotMode, test.wantMode)
				}

				// We increment the acceptance counter when checking the prompt file
				// before prompting, so start a second, transient gopls session and
				// verify that the acceptance counter is incremented.
				env2 := ConnectGoplsEnv(t, env.Ctx, env.Sandbox, env.Editor.Config(), env.Server)
				env2.Await(CompletedWork(server.TelemetryPromptWorkTitle, 1, true))
				if err := env2.Editor.Close(env2.Ctx); err != nil {
					t.Errorf("closing second editor: %v", err)
				}

				gotCounts := readCounts(t)
				for k := range gotCounts {
					gotCounts[k] -= initialCounts[k]
				}
				if diff := cmp.Diff(test.wantCounts, gotCounts); diff != "" {
					t.Errorf("counter mismatch (-want +got):\n%s", diff)
				}
			})
		})
	}
}

// Test that we stop asking about telemetry after the user ignores the question
// 5 times.
func TestTelemetryPrompt_GivingUp(t *testing.T) {
	const src = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {
}
`

	// For this test, we want to share state across gopls sessions.
	modeFile := filepath.Join(t.TempDir(), "mode")
	telemetryStartTime := time.Now().Add(-30 * 24 * time.Hour)
	configDir := t.TempDir()

	const maxPrompts = 5 // internal prompt limit defined by gopls

	for i := 0; i < maxPrompts+1; i++ {
		WithOptions(
			Modes(Default), // no need to run this in all modes
			EnvVars{
				server.GoplsConfigDirEnvvar:                  configDir,
				server.FakeTelemetryModefileEnvvar:           modeFile,
				server.GoTelemetryGoplsClientStartTimeEnvvar: strconv.FormatInt(telemetryStartTime.Unix(), 10),
				server.GoTelemetryGoplsClientTokenEnvvar:     "1", // always sample because samplingPerMille >= 1.
			},
			Settings{
				"telemetryPrompt": true,
			},
		).Run(t, src, func(t *testing.T, env *Env) {
			wantPrompt := i < maxPrompts
			expectation := ShownMessageRequest(".*Would you like to enable Go telemetry?")
			if !wantPrompt {
				expectation = Not(expectation)
			}
			env.OnceMet(
				CompletedWork(server.TelemetryPromptWorkTitle, 1, true),
				expectation,
			)
		})
	}
}

// Test that gopls prompts for telemetry only when it is supposed to.
func TestTelemetryPrompt_Conditions_Command(t *testing.T) {
	const src = `
-- go.mod --
module mod.com

go 1.12
-- main.go --
package main

func main() {
}
`
	modeFile := filepath.Join(t.TempDir(), "mode")
	telemetryStartTime := time.Now().Add(-8 * 24 * time.Hour)
	WithOptions(
		Modes(Default), // no need to run this in all modes
		EnvVars{
			server.GoplsConfigDirEnvvar:                  t.TempDir(),
			server.FakeTelemetryModefileEnvvar:           modeFile,
			server.GoTelemetryGoplsClientStartTimeEnvvar: fmt.Sprintf("%d", telemetryStartTime.Unix()),
			server.GoTelemetryGoplsClientTokenEnvvar:     "1", // always sample because samplingPerMille >= 1.
		},
		Settings{
			// off because we are testing
			// if we can trigger the prompt with command.
			"telemetryPrompt": false,
		},
	).Run(t, src, func(t *testing.T, env *Env) {
		cmd := command.NewMaybePromptForTelemetryCommand("prompt")
		var err error
		env.ExecuteCommand(&protocol.ExecuteCommandParams{
			Command: cmd.Command,
		}, &err)
		if err != nil {
			t.Fatal(err)
		}
		expectation := ShownMessageRequest(".*Would you like to enable Go telemetry?")
		env.OnceMet(
			CompletedWork(server.TelemetryPromptWorkTitle, 2, true),
			expectation,
		)
	})
}
