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

import (
	"context"
	"fmt"
	"math/rand"
	"os"
	"path/filepath"
	"strconv"
	"time"

	"golang.org/x/telemetry"
	"golang.org/x/telemetry/counter"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/internal/event"
)

// promptTimeout is the amount of time we wait for an ongoing prompt before
// prompting again. This gives the user time to reply. However, at some point
// we must assume that the client is not displaying the prompt, the user is
// ignoring it, or the prompt has been disrupted in some way (e.g. by a gopls
// crash).
const promptTimeout = 24 * time.Hour

// gracePeriod is the amount of time we wait before sufficient telemetry data
// is accumulated in the local directory, so users can have time to review
// what kind of information will be collected and uploaded when prompting starts.
const gracePeriod = 7 * 24 * time.Hour

// samplesPerMille is the prompt probability.
// Token is an integer between [1, 1000] and is assigned when maybePromptForTelemetry
// is called first time. Only the user with a token ∈ [1, samplesPerMille]
// will be considered for prompting.
const samplesPerMille = 10 // 1% sample rate

// The following constants are used for testing telemetry integration.
const (
	TelemetryPromptWorkTitle    = "Checking telemetry prompt"     // progress notification title, for awaiting in tests
	GoplsConfigDirEnvvar        = "GOPLS_CONFIG_DIR"              // overridden for testing
	FakeTelemetryModefileEnvvar = "GOPLS_FAKE_TELEMETRY_MODEFILE" // overridden for testing
	FakeSamplesPerMille         = "GOPLS_FAKE_SAMPLES_PER_MILLE"  // overridden for testing
	TelemetryYes                = "Yes, I'd like to help."
	TelemetryNo                 = "No, thanks."
)

// The following environment variables may be set by the client.
// Exported for testing telemetry integration.
const (
	GoTelemetryGoplsClientStartTimeEnvvar = "GOTELEMETRY_GOPLS_CLIENT_START_TIME" // telemetry start time recored in client
	GoTelemetryGoplsClientTokenEnvvar     = "GOTELEMETRY_GOPLS_CLIENT_TOKEN"      // sampling token
)

// getenv returns the effective environment variable value for the provided
// key, looking up the key in the session environment before falling back on
// the process environment.
func (s *server) getenv(key string) string {
	if v, ok := s.Options().Env[key]; ok {
		return v
	}
	return os.Getenv(key)
}

// configDir returns the root of the gopls configuration dir. By default this
// is os.UserConfigDir/gopls, but it may be overridden for tests.
func (s *server) configDir() (string, error) {
	if d := s.getenv(GoplsConfigDirEnvvar); d != "" {
		return d, nil
	}
	userDir, err := os.UserConfigDir()
	if err != nil {
		return "", err
	}
	return filepath.Join(userDir, "gopls"), nil
}

// telemetryMode returns the current effective telemetry mode.
// By default this is x/telemetry.Mode(), but it may be overridden for tests.
func (s *server) telemetryMode() string {
	if fake := s.getenv(FakeTelemetryModefileEnvvar); fake != "" {
		if data, err := os.ReadFile(fake); err == nil {
			return string(data)
		}
		return "local"
	}
	return telemetry.Mode()
}

// setTelemetryMode sets the current telemetry mode.
// By default this calls x/telemetry.SetMode, but it may be overridden for
// tests.
func (s *server) setTelemetryMode(mode string) error {
	if fake := s.getenv(FakeTelemetryModefileEnvvar); fake != "" {
		return os.WriteFile(fake, []byte(mode), 0666)
	}
	return telemetry.SetMode(mode)
}

// maybePromptForTelemetry checks for the right conditions, and then prompts
// the user to ask if they want to enable Go telemetry uploading. If the user
// responds 'Yes', the telemetry mode is set to "on".
//
// The actual conditions for prompting are defensive, erring on the side of not
// prompting.
// If enabled is false, this will not prompt the user in any condition,
// but will send work progress reports to help testing.
func (s *server) maybePromptForTelemetry(ctx context.Context, enabled bool) {
	if s.Options().VerboseWorkDoneProgress {
		work := s.progress.Start(ctx, TelemetryPromptWorkTitle, "Checking if gopls should prompt about telemetry...", nil, nil)
		defer work.End(ctx, "Done.")
	}

	errorf := func(format string, args ...any) {
		err := fmt.Errorf(format, args...)
		event.Error(ctx, "telemetry prompt failed", err)
	}

	// Only prompt if we can read/write the prompt config file.
	configDir, err := s.configDir()
	if err != nil {
		errorf("unable to determine config dir: %v", err)
		return
	}

	// Read the current prompt file.

	var (
		promptDir  = filepath.Join(configDir, "prompt")    // prompt configuration directory
		promptFile = filepath.Join(promptDir, "telemetry") // telemetry prompt file
	)

	// prompt states, stored in the prompt file
	const (
		pUnknown  = ""        // first time
		pNotReady = "-"       // user is not asked yet (either not sampled or not past the grace period)
		pYes      = "yes"     // user said yes
		pNo       = "no"      // user said no
		pPending  = "pending" // current prompt is still pending
		pFailed   = "failed"  // prompt was asked but failed
	)
	validStates := map[string]bool{
		pNotReady: true,
		pYes:      true,
		pNo:       true,
		pPending:  true,
		pFailed:   true,
	}

	// Parse the current prompt file.
	var (
		state    = pUnknown
		attempts = 0 // number of times we've asked already

		// the followings are recorded after gopls v0.17+.
		token        = 0   // valid token is [1, 1000]
		creationTime int64 // unix time sec
	)
	if content, err := os.ReadFile(promptFile); err == nil {
		if n, _ := fmt.Sscanf(string(content), "%s %d %d %d", &state, &attempts, &creationTime, &token); (n == 2 || n == 4) && validStates[state] {
			// successfully parsed!
			//  ~ v0.16: must have only two fields, state and attempts.
			//  v0.17 ~: must have all four fields.
		} else {
			state, attempts, creationTime, token = pUnknown, 0, 0, 0
			errorf("malformed prompt result %q", string(content))
		}
	} else if !os.IsNotExist(err) {
		errorf("reading prompt file: %v", err)
		// Something went wrong. Since we don't know how many times we've asked the
		// prompt, err on the side of not asking.
		//
		// But record this in telemetry, in case some users enable telemetry by
		// other means.
		counter.New("gopls/telemetryprompt/corrupted").Inc()
		return
	}

	counter.New(fmt.Sprintf("gopls/telemetryprompt/attempts:%d", attempts)).Inc()

	// Check terminal conditions.

	if state == pYes {
		// Prompt has been accepted.
		//
		// We record this counter for every gopls session, rather than when the
		// prompt actually accepted below, because if we only recorded it in the
		// counter file at the time telemetry is enabled, we'd never upload it,
		// because we exclude any counter files that overlap with a time period
		// that has telemetry uploading is disabled.
		counter.New("gopls/telemetryprompt/accepted").Inc()
		return
	}
	if state == pNo {
		// Prompt has been declined. In most cases, this means we'll never see the
		// counter below, but it's possible that the user may enable telemetry by
		// other means later on. If we see a significant number of users that have
		// accepted telemetry but declined the prompt, it may be an indication that
		// the prompt is not working well.
		counter.New("gopls/telemetryprompt/declined").Inc()
		return
	}
	if attempts >= 5 { // pPending or pFailed
		// We've tried asking enough; give up. Record that the prompt expired, in
		// case the user decides to enable telemetry by other means later on.
		// (see also the pNo case).
		counter.New("gopls/telemetryprompt/expired").Inc()
		return
	}

	// We only check enabled after (1) the work progress is started, and (2) the
	// prompt file has been read. (1) is for testing purposes, and (2) is so that
	// we record the "gopls/telemetryprompt/accepted" counter for every session.
	if !enabled {
		return // prompt is disabled
	}

	if s.telemetryMode() == "on" || s.telemetryMode() == "off" {
		// Telemetry is already on or explicitly off -- nothing to ask about.
		return
	}

	// Transition: pUnknown -> pNotReady
	if state == pUnknown {
		// First time; we need to make the prompt dir.
		if err := os.MkdirAll(promptDir, 0777); err != nil {
			errorf("creating prompt dir: %v", err)
			return
		}
		state = pNotReady
	}

	// Correct missing values.
	if creationTime == 0 {
		creationTime = time.Now().Unix()
		if v := s.getenv(GoTelemetryGoplsClientStartTimeEnvvar); v != "" {
			if sec, err := strconv.ParseInt(v, 10, 64); err == nil && sec > 0 {
				creationTime = sec
			}
		}
	}
	if token == 0 {
		token = rand.Intn(1000) + 1
		if v := s.getenv(GoTelemetryGoplsClientTokenEnvvar); v != "" {
			if tok, err := strconv.Atoi(v); err == nil && 1 <= tok && tok <= 1000 {
				token = tok
			}
		}
	}

	// Transition: pNotReady -> pPending if sampled
	if state == pNotReady {
		threshold := samplesPerMille
		if v := s.getenv(FakeSamplesPerMille); v != "" {
			if t, err := strconv.Atoi(v); err == nil {
				threshold = t
			}
		}
		if token <= threshold && time.Now().Unix()-creationTime > gracePeriod.Milliseconds()/1000 {
			state = pPending
		}
	}

	// Acquire the lock and write the updated state to the prompt file before actually
	// prompting.
	//
	// This ensures that the prompt file is writeable, and that we increment the
	// attempt counter before we prompt, so that we don't end up in a failure
	// mode where we keep prompting and then failing to record the response.

	release, ok, err := acquireLockFile(promptFile)
	if err != nil {
		errorf("acquiring prompt: %v", err)
		return
	}
	if !ok {
		// Another process is making decision.
		return
	}
	defer release()

	if state != pNotReady { // pPending or pFailed
		attempts++
	}

	pendingContent := []byte(fmt.Sprintf("%s %d %d %d", state, attempts, creationTime, token))
	if err := os.WriteFile(promptFile, pendingContent, 0666); err != nil {
		errorf("writing pending state: %v", err)
		return
	}

	if state == pNotReady {
		return
	}

	var prompt = `Go telemetry helps us improve Go by periodically sending anonymous metrics and crash reports to the Go team. Learn more at https://go.dev/doc/telemetry.

Would you like to enable Go telemetry?
`
	if s.Options().LinkifyShowMessage {
		prompt = `Go telemetry helps us improve Go by periodically sending anonymous metrics and crash reports to the Go team. Learn more at [go.dev/doc/telemetry](https://go.dev/doc/telemetry).

Would you like to enable Go telemetry?
`
	}
	// TODO(rfindley): investigate a "tell me more" action in combination with ShowDocument.
	params := &protocol.ShowMessageRequestParams{
		Type:    protocol.Info,
		Message: prompt,
		Actions: []protocol.MessageActionItem{
			{Title: TelemetryYes},
			{Title: TelemetryNo},
		},
	}

	item, err := s.client.ShowMessageRequest(ctx, params)
	if err != nil {
		errorf("ShowMessageRequest failed: %v", err)
		// Defensive: ensure item == nil for the logic below.
		item = nil
	}

	message := func(typ protocol.MessageType, msg string) {
		if !showMessage(ctx, s.client, typ, msg) {
			// Make sure we record that "telemetry prompt failed".
			errorf("showMessage failed: %v", err)
		}
	}

	result := pFailed
	if item == nil {
		// e.g. dialog was dismissed
		errorf("no response")
	} else {
		// Response matches MessageActionItem.Title.
		switch item.Title {
		case TelemetryYes:
			result = pYes
			if err := s.setTelemetryMode("on"); err == nil {
				message(protocol.Info, telemetryOnMessage(s.Options().LinkifyShowMessage))
			} else {
				errorf("enabling telemetry failed: %v", err)
				msg := fmt.Sprintf("Failed to enable Go telemetry: %v\nTo enable telemetry manually, please run `go run golang.org/x/telemetry/cmd/gotelemetry@latest on`", err)
				message(protocol.Error, msg)
			}

		case TelemetryNo:
			result = pNo
		default:
			errorf("unrecognized response %q", item.Title)
			message(protocol.Error, fmt.Sprintf("Unrecognized response %q", item.Title))
		}
	}
	resultContent := []byte(fmt.Sprintf("%s %d %d %d", result, attempts, creationTime, token))
	if err := os.WriteFile(promptFile, resultContent, 0666); err != nil {
		errorf("error writing result state to prompt file: %v", err)
	}
}

func telemetryOnMessage(linkify bool) string {
	format := `Thank you. Telemetry uploading is now enabled.

To disable telemetry uploading, run %s.
`
	var runCmd = "`go run golang.org/x/telemetry/cmd/gotelemetry@latest local`"
	if linkify {
		runCmd = "[gotelemetry local](https://golang.org/x/telemetry/cmd/gotelemetry)"
	}
	return fmt.Sprintf(format, runCmd)
}

// acquireLockFile attempts to "acquire a lock" for writing to path.
//
// This is achieved by creating an exclusive lock file at <path>.lock. Lock
// files expire after a period, at which point acquireLockFile will remove and
// recreate the lock file.
//
// acquireLockFile fails if path is in a directory that doesn't exist.
func acquireLockFile(path string) (func(), bool, error) {
	lockpath := path + ".lock"
	fi, err := os.Stat(lockpath)
	if err == nil {
		if time.Since(fi.ModTime()) > promptTimeout {
			_ = os.Remove(lockpath) // ignore error
		} else {
			return nil, false, nil
		}
	} else if !os.IsNotExist(err) {
		return nil, false, fmt.Errorf("statting lockfile: %v", err)
	}

	f, err := os.OpenFile(lockpath, os.O_CREATE|os.O_EXCL, 0666)
	if err != nil {
		if os.IsExist(err) {
			return nil, false, nil
		}
		return nil, false, fmt.Errorf("creating lockfile: %v", err)
	}
	fi, err = f.Stat()
	if err != nil {
		return nil, false, err
	}
	release := func() {
		_ = f.Close() // ignore error
		fi2, err := os.Stat(lockpath)
		if err == nil && os.SameFile(fi, fi2) {
			// Only clean up the lockfile if it's the same file we created.
			// Otherwise, our lock has expired and something else has the lock.
			//
			// There's a race here, in that the file could have changed since the
			// stat above; but given that we've already waited 24h this is extremely
			// unlikely, and acceptable.
			_ = os.Remove(lockpath)
		}
	}
	return release, true, nil
}
