// Copyright 2020 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 regtest

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"sync"
	"testing"

	"golang.org/x/tools/internal/jsonrpc2/servertest"
	"golang.org/x/tools/internal/lsp/fake"
	"golang.org/x/tools/internal/lsp/protocol"
)

// Env holds an initialized fake Editor, Workspace, and Server, which may be
// used for writing tests. It also provides adapter methods that call t.Fatal
// on any error, so that tests for the happy path may be written without
// checking errors.
type Env struct {
	T   *testing.T
	Ctx context.Context

	// Most tests should not need to access the scratch area, editor, server, or
	// connection, but they are available if needed.
	Sandbox *fake.Sandbox
	Editor  *fake.Editor
	Server  servertest.Connector

	// mu guards the fields below, for the purpose of checking conditions on
	// every change to diagnostics.
	mu sync.Mutex
	// For simplicity, each waiter gets a unique ID.
	nextWaiterID int
	state        State
	waiters      map[int]*condition
}

// State encapsulates the server state TODO: explain more
type State struct {
	// diagnostics are a map of relative path->diagnostics params
	diagnostics        map[string]*protocol.PublishDiagnosticsParams
	logs               []*protocol.LogMessageParams
	showMessage        []*protocol.ShowMessageParams
	showMessageRequest []*protocol.ShowMessageRequestParams
	// outstandingWork is a map of token->work summary. All tokens are assumed to
	// be string, though the spec allows for numeric tokens as well.  When work
	// completes, it is deleted from this map.
	outstandingWork map[string]*workProgress
	completedWork   map[string]int
}

type workProgress struct {
	title   string
	percent float64
}

func (s State) String() string {
	var b strings.Builder
	b.WriteString("#### log messages (see RPC logs for full text):\n")
	for _, msg := range s.logs {
		summary := fmt.Sprintf("%v: %q", msg.Type, msg.Message)
		if len(summary) > 60 {
			summary = summary[:57] + "..."
		}
		// Some logs are quite long, and since they should be reproduced in the RPC
		// logs on any failure we include here just a short summary.
		fmt.Fprint(&b, "\t"+summary+"\n")
	}
	b.WriteString("\n")
	b.WriteString("#### diagnostics:\n")
	for name, params := range s.diagnostics {
		fmt.Fprintf(&b, "\t%s (version %d):\n", name, int(params.Version))
		for _, d := range params.Diagnostics {
			fmt.Fprintf(&b, "\t\t(%d, %d): %s\n", int(d.Range.Start.Line), int(d.Range.Start.Character), d.Message)
		}
	}
	b.WriteString("\n")
	b.WriteString("#### outstanding work:\n")
	for token, state := range s.outstandingWork {
		name := state.title
		if name == "" {
			name = fmt.Sprintf("!NO NAME(token: %s)", token)
		}
		fmt.Fprintf(&b, "\t%s: %.2f\n", name, state.percent)
	}
	b.WriteString("#### completed work:\n")
	for name, count := range s.completedWork {
		fmt.Fprintf(&b, "\t%s: %d\n", name, count)
	}
	return b.String()
}

// A condition is satisfied when all expectations are simultaneously
// met. At that point, the 'met' channel is closed. On any failure, err is set
// and the failed channel is closed.
type condition struct {
	expectations []Expectation
	verdict      chan Verdict
}

// NewEnv creates a new test environment using the given scratch environment
// and gopls server.
func NewEnv(ctx context.Context, t *testing.T, scratch *fake.Sandbox, ts servertest.Connector, editorConfig fake.EditorConfig) *Env {
	t.Helper()
	conn := ts.Connect(ctx)
	env := &Env{
		T:       t,
		Ctx:     ctx,
		Sandbox: scratch,
		Server:  ts,
		state: State{
			diagnostics:     make(map[string]*protocol.PublishDiagnosticsParams),
			outstandingWork: make(map[string]*workProgress),
			completedWork:   make(map[string]int),
		},
		waiters: make(map[int]*condition),
	}
	hooks := fake.ClientHooks{
		OnDiagnostics:            env.onDiagnostics,
		OnLogMessage:             env.onLogMessage,
		OnWorkDoneProgressCreate: env.onWorkDoneProgressCreate,
		OnProgress:               env.onProgress,
		OnShowMessage:            env.onShowMessage,
		OnShowMessageRequest:     env.onShowMessageRequest,
	}
	editor, err := fake.NewEditor(scratch, editorConfig).Connect(ctx, conn, hooks)
	if err != nil {
		t.Fatal(err)
	}
	env.Editor = editor
	return env
}

func (e *Env) onDiagnostics(_ context.Context, d *protocol.PublishDiagnosticsParams) error {
	e.mu.Lock()
	defer e.mu.Unlock()

	pth := e.Sandbox.Workdir.URIToPath(d.URI)
	e.state.diagnostics[pth] = d
	e.checkConditionsLocked()
	return nil
}

func (e *Env) onShowMessage(_ context.Context, m *protocol.ShowMessageParams) error {
	e.mu.Lock()
	defer e.mu.Unlock()

	e.state.showMessage = append(e.state.showMessage, m)
	e.checkConditionsLocked()
	return nil
}

func (e *Env) onShowMessageRequest(_ context.Context, m *protocol.ShowMessageRequestParams) error {
	e.mu.Lock()
	defer e.mu.Unlock()

	e.state.showMessageRequest = append(e.state.showMessageRequest, m)
	e.checkConditionsLocked()
	return nil
}

func (e *Env) onLogMessage(_ context.Context, m *protocol.LogMessageParams) error {
	e.mu.Lock()
	defer e.mu.Unlock()

	e.state.logs = append(e.state.logs, m)
	e.checkConditionsLocked()
	return nil
}

func (e *Env) onWorkDoneProgressCreate(_ context.Context, m *protocol.WorkDoneProgressCreateParams) error {
	e.mu.Lock()
	defer e.mu.Unlock()

	token := m.Token.(string)
	e.state.outstandingWork[token] = &workProgress{}
	return nil
}

func (e *Env) onProgress(_ context.Context, m *protocol.ProgressParams) error {
	e.mu.Lock()
	defer e.mu.Unlock()
	token := m.Token.(string)
	work, ok := e.state.outstandingWork[token]
	if !ok {
		panic(fmt.Sprintf("got progress report for unknown report %s: %v", token, m))
	}
	v := m.Value.(map[string]interface{})
	switch kind := v["kind"]; kind {
	case "begin":
		work.title = v["title"].(string)
	case "report":
		if pct, ok := v["percentage"]; ok {
			work.percent = pct.(float64)
		}
	case "end":
		title := e.state.outstandingWork[token].title
		e.state.completedWork[title] = e.state.completedWork[title] + 1
		delete(e.state.outstandingWork, token)
	}
	e.checkConditionsLocked()
	return nil
}

func (e *Env) checkConditionsLocked() {
	for id, condition := range e.waiters {
		if v, _, _ := checkExpectations(e.state, condition.expectations); v != Unmet {
			delete(e.waiters, id)
			condition.verdict <- v
		}
	}
}

// ExpectNow asserts that the current state of the editor matches the given
// expectations.
//
// It can be used together with Env.Await to allow waiting on
// simple expectations, followed by more detailed expectations tested by
// ExpectNow. For example:
//
//  env.RegexpReplace("foo.go", "a", "x")
//  env.Await(env.AnyDiagnosticAtCurrentVersion("foo.go"))
//  env.ExpectNow(env.DiagnosticAtRegexp("foo.go", "x"))
//
// This has the advantage of not timing out if the diagnostic received for
// "foo.go" does not match the expectation: instead it fails early.
func (e *Env) ExpectNow(expectations ...Expectation) {
	e.T.Helper()
	e.mu.Lock()
	defer e.mu.Unlock()
	if verdict, summary, _ := checkExpectations(e.state, expectations); verdict != Met {
		e.T.Fatalf("expectations unmet:\n%s\ncurrent state:\n%v", summary, e.state)
	}
}

// checkExpectations reports whether s meets all expectations.
func checkExpectations(s State, expectations []Expectation) (Verdict, string, []interface{}) {
	finalVerdict := Met
	var metBy []interface{}
	var summary strings.Builder
	for _, e := range expectations {
		v, mb := e.Check(s)
		if v == Met {
			metBy = append(metBy, mb)
		}
		if v > finalVerdict {
			finalVerdict = v
		}
		summary.WriteString(fmt.Sprintf("\t%v: %s\n", v, e.Description()))
	}
	return finalVerdict, summary.String(), metBy
}

// An Expectation asserts that the state of the editor at a point in time
// matches an expected condition. This is used for signaling in tests when
// certain conditions in the editor are met.
type Expectation interface {
	// Check determines whether the state of the editor satisfies the
	// expectation, returning the results that met the condition.
	Check(State) (Verdict, interface{})
	// Description is a human-readable description of the expectation.
	Description() string
}

// A Verdict is the result of checking an expectation against the current
// editor state.
type Verdict int

// Order matters for the following constants: verdicts are sorted in order of
// decisiveness.
const (
	// Met indicates that an expectation is satisfied by the current state.
	Met Verdict = iota
	// Unmet indicates that an expectation is not currently met, but could be met
	// in the future.
	Unmet
	// Unmeetable indicates that an expectation cannot be satisfied in the
	// future.
	Unmeetable
)

// OnceMet returns an Expectation that, once the precondition is met, asserts
// that mustMeet is met.
func OnceMet(precondition Expectation, mustMeet Expectation) *SimpleExpectation {
	check := func(s State) (Verdict, interface{}) {
		switch pre, _ := precondition.Check(s); pre {
		case Unmeetable:
			return Unmeetable, nil
		case Met:
			verdict, metBy := mustMeet.Check(s)
			if verdict != Met {
				return Unmeetable, metBy
			}
			return Met, metBy
		default:
			return Unmet, nil
		}
	}
	return &SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("once %q is met, must have %q", precondition.Description(), mustMeet.Description()),
	}
}

func (v Verdict) String() string {
	switch v {
	case Met:
		return "Met"
	case Unmet:
		return "Unmet"
	case Unmeetable:
		return "Unmeetable"
	}
	return fmt.Sprintf("unrecognized verdict %d", v)
}

// SimpleExpectation holds an arbitrary check func, and implements the Expectation interface.
type SimpleExpectation struct {
	check       func(State) (Verdict, interface{})
	description string
}

// Check invokes e.check.
func (e SimpleExpectation) Check(s State) (Verdict, interface{}) {
	return e.check(s)
}

// Description returns e.descriptin.
func (e SimpleExpectation) Description() string {
	return e.description
}

// NoOutstandingWork asserts that there is no work initiated using the LSP
// $/progress API that has not completed.
func NoOutstandingWork() SimpleExpectation {
	check := func(s State) (Verdict, interface{}) {
		if len(s.outstandingWork) == 0 {
			return Met, nil
		}
		return Unmet, nil
	}
	return SimpleExpectation{
		check:       check,
		description: "no outstanding work",
	}
}

// EmptyShowMessage asserts that the editor has not received a ShowMessage.
func EmptyShowMessage(title string) SimpleExpectation {
	check := func(s State) (Verdict, interface{}) {
		if len(s.showMessage) == 0 {
			return Met, title
		}
		return Unmeetable, nil
	}
	return SimpleExpectation{
		check:       check,
		description: "no ShowMessage received",
	}
}

// SomeShowMessage asserts that the editor has received a ShowMessage.
func SomeShowMessage(title string) SimpleExpectation {
	check := func(s State) (Verdict, interface{}) {
		if len(s.showMessage) > 0 {
			return Met, title
		}
		return Unmet, nil
	}
	return SimpleExpectation{
		check:       check,
		description: "received ShowMessage",
	}
}

// ShowMessageRequest asserts that the editor has received a ShowMessageRequest
// with an action item that has the given title.
func ShowMessageRequest(title string) SimpleExpectation {
	check := func(s State) (Verdict, interface{}) {
		if len(s.showMessageRequest) == 0 {
			return Unmet, nil
		}
		// Only check the most recent one.
		m := s.showMessageRequest[len(s.showMessageRequest)-1]
		if len(m.Actions) == 0 || len(m.Actions) > 1 {
			return Unmet, nil
		}
		if m.Actions[0].Title == title {
			return Met, m.Actions[0]
		}
		return Unmet, nil
	}
	return SimpleExpectation{
		check:       check,
		description: "received ShowMessageRequest",
	}
}

// CompletedWork expects a work item to have been completed >= atLeast times.
//
// Since the Progress API doesn't include any hidden metadata, we must use the
// progress notification title to identify the work we expect to be completed.
func CompletedWork(title string, atLeast int) SimpleExpectation {
	check := func(s State) (Verdict, interface{}) {
		if s.completedWork[title] >= atLeast {
			return Met, title
		}
		return Unmet, nil
	}
	return SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("completed work %q at least %d time(s)", title, atLeast),
	}
}

// LogExpectation is an expectation on the log messages received by the editor
// from gopls.
type LogExpectation struct {
	check       func([]*protocol.LogMessageParams) (Verdict, interface{})
	description string
}

// Check implements the Expectation interface.
func (e LogExpectation) Check(s State) (Verdict, interface{}) {
	return e.check(s.logs)
}

// Description implements the Expectation interface.
func (e LogExpectation) Description() string {
	return e.description
}

// NoErrorLogs asserts that the client has not received any log messages of
// error severity.
func NoErrorLogs() LogExpectation {
	check := func(msgs []*protocol.LogMessageParams) (Verdict, interface{}) {
		for _, msg := range msgs {
			if msg.Type == protocol.Error {
				return Unmeetable, nil
			}
		}
		return Met, nil
	}
	return LogExpectation{
		check:       check,
		description: "no errors have been logged",
	}
}

// LogMatching asserts that the client has received a log message
// matching of type typ matching the regexp re.
func LogMatching(typ protocol.MessageType, re string) LogExpectation {
	rec, err := regexp.Compile(re)
	if err != nil {
		panic(err)
	}
	check := func(msgs []*protocol.LogMessageParams) (Verdict, interface{}) {
		for _, msg := range msgs {
			if msg.Type == typ && rec.Match([]byte(msg.Message)) {
				return Met, msg
			}
		}
		return Unmet, nil
	}
	return LogExpectation{
		check:       check,
		description: fmt.Sprintf("log message matching %q", re),
	}
}

// A DiagnosticExpectation is a condition that must be met by the current set
// of diagnostics for a file.
type DiagnosticExpectation struct {
	// IsMet determines whether the diagnostics for this file version satisfy our
	// expectation.
	isMet func(*protocol.PublishDiagnosticsParams) bool
	// Description is a human-readable description of the diagnostic expectation.
	description string
	// Path is the scratch workdir-relative path to the file being asserted on.
	path string
}

// Check implements the Expectation interface.
func (e DiagnosticExpectation) Check(s State) (Verdict, interface{}) {
	if diags, ok := s.diagnostics[e.path]; ok && e.isMet(diags) {
		return Met, diags
	}
	return Unmet, nil
}

// Description implements the Expectation interface.
func (e DiagnosticExpectation) Description() string {
	return fmt.Sprintf("%s: %s", e.path, e.description)
}

// EmptyDiagnostics asserts that empty diagnostics are sent for the
// workspace-relative path name.
func EmptyDiagnostics(name string) Expectation {
	check := func(s State) (Verdict, interface{}) {
		if diags := s.diagnostics[name]; diags != nil && len(diags.Diagnostics) == 0 {
			return Met, nil
		}
		return Unmet, nil
	}
	return SimpleExpectation{
		check:       check,
		description: "empty diagnostics",
	}
}

// NoDiagnostics asserts that no diagnostics are sent for the
// workspace-relative path name. It should be used primarily in conjunction
// with a OnceMet, as it has to check that all outstanding diagnostics have
// already been delivered.
func NoDiagnostics(name string) Expectation {
	check := func(s State) (Verdict, interface{}) {
		if _, ok := s.diagnostics[name]; !ok {
			return Met, nil
		}
		return Unmet, nil
	}
	return SimpleExpectation{
		check:       check,
		description: "no diagnostics",
	}
}

// AnyDiagnosticAtCurrentVersion asserts that there is a diagnostic report for
// the current edited version of the buffer corresponding to the given
// workdir-relative pathname.
func (e *Env) AnyDiagnosticAtCurrentVersion(name string) DiagnosticExpectation {
	version := e.Editor.BufferVersion(name)
	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
		return int(diags.Version) == version
	}
	return DiagnosticExpectation{
		isMet:       isMet,
		description: fmt.Sprintf("any diagnostics at version %d", version),
		path:        name,
	}
}

// DiagnosticAtRegexp expects that there is a diagnostic entry at the start
// position matching the regexp search string re in the buffer specified by
// name. Note that this currently ignores the end position.
func (e *Env) DiagnosticAtRegexp(name, re string) DiagnosticExpectation {
	e.T.Helper()
	pos := e.RegexpSearch(name, re)
	expectation := DiagnosticAt(name, pos.Line, pos.Column)
	expectation.description += fmt.Sprintf(" (location of %q)", re)
	return expectation
}

// DiagnosticAt asserts that there is a diagnostic entry at the position
// specified by line and col, for the workdir-relative path name.
func DiagnosticAt(name string, line, col int) DiagnosticExpectation {
	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
		for _, d := range diags.Diagnostics {
			if d.Range.Start.Line == float64(line) && d.Range.Start.Character == float64(col) {
				return true
			}
		}
		return false
	}
	return DiagnosticExpectation{
		isMet:       isMet,
		description: fmt.Sprintf("diagnostic at {line:%d, column:%d}", line, col),
		path:        name,
	}
}

// DiagnosticsFor returns the current diagnostics for the file. It is useful
// after waiting on AnyDiagnosticAtCurrentVersion, when the desired diagnostic
// is not simply described by DiagnosticAt.
func (e *Env) DiagnosticsFor(name string) *protocol.PublishDiagnosticsParams {
	e.mu.Lock()
	defer e.mu.Unlock()
	return e.state.diagnostics[name]
}

// Await waits for all expectations to simultaneously be met. It should only be
// called from the main test goroutine.
func (e *Env) Await(expectations ...Expectation) []interface{} {
	e.T.Helper()
	e.mu.Lock()
	// Before adding the waiter, we check if the condition is currently met or
	// failed to avoid a race where the condition was realized before Await was
	// called.
	switch verdict, summary, metBy := checkExpectations(e.state, expectations); verdict {
	case Met:
		e.mu.Unlock()
		return metBy
	case Unmeetable:
		e.mu.Unlock()
		e.T.Fatalf("unmeetable expectations:\n%s\nstate:\n%v", summary, e.state)
	}
	cond := &condition{
		expectations: expectations,
		verdict:      make(chan Verdict),
	}
	e.waiters[e.nextWaiterID] = cond
	e.nextWaiterID++
	e.mu.Unlock()

	var err error
	select {
	case <-e.Ctx.Done():
		err = e.Ctx.Err()
	case v := <-cond.verdict:
		if v != Met {
			err = fmt.Errorf("condition has final verdict %v", v)
		}
	}
	e.mu.Lock()
	defer e.mu.Unlock()
	_, summary, metBy := checkExpectations(e.state, expectations)

	// Debugging an unmet expectation can be tricky, so we put some effort into
	// nicely formatting the failure.
	if err != nil {
		e.T.Fatalf("waiting on:\n%s\nerr:%v\n\nstate:\n%v", summary, err, e.state)
	}
	return metBy
}
