// 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 (
	"encoding/json"
	"path"

	"golang.org/x/tools/gopls/internal/lsp/command"
	"golang.org/x/tools/gopls/internal/lsp/fake"
	"golang.org/x/tools/gopls/internal/lsp/protocol"
	"golang.org/x/tools/internal/xcontext"
)

// RemoveWorkspaceFile deletes a file on disk but does nothing in the
// editor. It calls t.Fatal on any error.
func (e *Env) RemoveWorkspaceFile(name string) {
	e.T.Helper()
	if err := e.Sandbox.Workdir.RemoveFile(e.Ctx, name); err != nil {
		e.T.Fatal(err)
	}
}

// ReadWorkspaceFile reads a file from the workspace, calling t.Fatal on any
// error.
func (e *Env) ReadWorkspaceFile(name string) string {
	e.T.Helper()
	content, err := e.Sandbox.Workdir.ReadFile(name)
	if err != nil {
		e.T.Fatal(err)
	}
	return string(content)
}

// WriteWorkspaceFile writes a file to disk but does nothing in the editor.
// It calls t.Fatal on any error.
func (e *Env) WriteWorkspaceFile(name, content string) {
	e.T.Helper()
	if err := e.Sandbox.Workdir.WriteFile(e.Ctx, name, content); err != nil {
		e.T.Fatal(err)
	}
}

// WriteWorkspaceFiles deletes a file on disk but does nothing in the
// editor. It calls t.Fatal on any error.
func (e *Env) WriteWorkspaceFiles(files map[string]string) {
	e.T.Helper()
	if err := e.Sandbox.Workdir.WriteFiles(e.Ctx, files); err != nil {
		e.T.Fatal(err)
	}
}

// ListFiles lists relative paths to files in the given directory.
// It calls t.Fatal on any error.
func (e *Env) ListFiles(dir string) []string {
	e.T.Helper()
	paths, err := e.Sandbox.Workdir.ListFiles(dir)
	if err != nil {
		e.T.Fatal(err)
	}
	return paths
}

// OpenFile opens a file in the editor, calling t.Fatal on any error.
func (e *Env) OpenFile(name string) {
	e.T.Helper()
	if err := e.Editor.OpenFile(e.Ctx, name); err != nil {
		e.T.Fatal(err)
	}
}

// CreateBuffer creates a buffer in the editor, calling t.Fatal on any error.
func (e *Env) CreateBuffer(name string, content string) {
	e.T.Helper()
	if err := e.Editor.CreateBuffer(e.Ctx, name, content); err != nil {
		e.T.Fatal(err)
	}
}

// BufferText returns the current buffer contents for the file with the given
// relative path, calling t.Fatal if the file is not open in a buffer.
func (e *Env) BufferText(name string) string {
	e.T.Helper()
	text, ok := e.Editor.BufferText(name)
	if !ok {
		e.T.Fatalf("buffer %q is not open", name)
	}
	return text
}

// CloseBuffer closes an editor buffer without saving, calling t.Fatal on any
// error.
func (e *Env) CloseBuffer(name string) {
	e.T.Helper()
	if err := e.Editor.CloseBuffer(e.Ctx, name); err != nil {
		e.T.Fatal(err)
	}
}

// EditBuffer applies edits to an editor buffer, calling t.Fatal on any error.
func (e *Env) EditBuffer(name string, edits ...protocol.TextEdit) {
	e.T.Helper()
	if err := e.Editor.EditBuffer(e.Ctx, name, edits); err != nil {
		e.T.Fatal(err)
	}
}

func (e *Env) SetBufferContent(name string, content string) {
	e.T.Helper()
	if err := e.Editor.SetBufferContent(e.Ctx, name, content); err != nil {
		e.T.Fatal(err)
	}
}

// RegexpSearch returns the starting position of the first match for re in the
// buffer specified by name, calling t.Fatal on any error. It first searches
// for the position in open buffers, then in workspace files.
func (e *Env) RegexpSearch(name, re string) protocol.Location {
	e.T.Helper()
	loc, err := e.Editor.RegexpSearch(name, re)
	if err == fake.ErrUnknownBuffer {
		loc, err = e.Sandbox.Workdir.RegexpSearch(name, re)
	}
	if err != nil {
		e.T.Fatalf("RegexpSearch: %v, %v for %q", name, err, re)
	}
	return loc
}

// RegexpReplace replaces the first group in the first match of regexpStr with
// the replace text, calling t.Fatal on any error.
func (e *Env) RegexpReplace(name, regexpStr, replace string) {
	e.T.Helper()
	if err := e.Editor.RegexpReplace(e.Ctx, name, regexpStr, replace); err != nil {
		e.T.Fatalf("RegexpReplace: %v", err)
	}
}

// SaveBuffer saves an editor buffer, calling t.Fatal on any error.
func (e *Env) SaveBuffer(name string) {
	e.T.Helper()
	if err := e.Editor.SaveBuffer(e.Ctx, name); err != nil {
		e.T.Fatal(err)
	}
}

func (e *Env) SaveBufferWithoutActions(name string) {
	e.T.Helper()
	if err := e.Editor.SaveBufferWithoutActions(e.Ctx, name); err != nil {
		e.T.Fatal(err)
	}
}

// GoToDefinition goes to definition in the editor, calling t.Fatal on any
// error. It returns the path and position of the resulting jump.
func (e *Env) GoToDefinition(loc protocol.Location) protocol.Location {
	e.T.Helper()
	loc, err := e.Editor.GoToDefinition(e.Ctx, loc)
	if err != nil {
		e.T.Fatal(err)
	}
	return loc
}

// FormatBuffer formats the editor buffer, calling t.Fatal on any error.
func (e *Env) FormatBuffer(name string) {
	e.T.Helper()
	if err := e.Editor.FormatBuffer(e.Ctx, name); err != nil {
		e.T.Fatal(err)
	}
}

// OrganizeImports processes the source.organizeImports codeAction, calling
// t.Fatal on any error.
func (e *Env) OrganizeImports(name string) {
	e.T.Helper()
	if err := e.Editor.OrganizeImports(e.Ctx, name); err != nil {
		e.T.Fatal(err)
	}
}

// ApplyQuickFixes processes the quickfix codeAction, calling t.Fatal on any error.
func (e *Env) ApplyQuickFixes(path string, diagnostics []protocol.Diagnostic) {
	e.T.Helper()
	loc := protocol.Location{URI: e.Sandbox.Workdir.URI(path)} // zero Range => whole file
	if err := e.Editor.ApplyQuickFixes(e.Ctx, loc, diagnostics); err != nil {
		e.T.Fatal(err)
	}
}

// ApplyCodeAction applies the given code action.
func (e *Env) ApplyCodeAction(action protocol.CodeAction) {
	e.T.Helper()
	if err := e.Editor.ApplyCodeAction(e.Ctx, action); err != nil {
		e.T.Fatal(err)
	}
}

// GetQuickFixes returns the available quick fix code actions.
func (e *Env) GetQuickFixes(path string, diagnostics []protocol.Diagnostic) []protocol.CodeAction {
	e.T.Helper()
	loc := protocol.Location{URI: e.Sandbox.Workdir.URI(path)} // zero Range => whole file
	actions, err := e.Editor.GetQuickFixes(e.Ctx, loc, diagnostics)
	if err != nil {
		e.T.Fatal(err)
	}
	return actions
}

// Hover in the editor, calling t.Fatal on any error.
func (e *Env) Hover(loc protocol.Location) (*protocol.MarkupContent, protocol.Location) {
	e.T.Helper()
	c, loc, err := e.Editor.Hover(e.Ctx, loc)
	if err != nil {
		e.T.Fatal(err)
	}
	return c, loc
}

func (e *Env) DocumentLink(name string) []protocol.DocumentLink {
	e.T.Helper()
	links, err := e.Editor.DocumentLink(e.Ctx, name)
	if err != nil {
		e.T.Fatal(err)
	}
	return links
}

func (e *Env) DocumentHighlight(loc protocol.Location) []protocol.DocumentHighlight {
	e.T.Helper()
	highlights, err := e.Editor.DocumentHighlight(e.Ctx, loc)
	if err != nil {
		e.T.Fatal(err)
	}
	return highlights
}

// RunGenerate runs "go generate" in the given dir, calling t.Fatal on any error.
// It waits for the generate command to complete and checks for file changes
// before returning.
func (e *Env) RunGenerate(dir string) {
	e.T.Helper()
	if err := e.Editor.RunGenerate(e.Ctx, dir); err != nil {
		e.T.Fatal(err)
	}
	e.Await(NoOutstandingWork())
	// Ideally the fake.Workspace would handle all synthetic file watching, but
	// we help it out here as we need to wait for the generate command to
	// complete before checking the filesystem.
	e.CheckForFileChanges()
}

// RunGoCommand runs the given command in the sandbox's default working
// directory.
func (e *Env) RunGoCommand(verb string, args ...string) {
	e.T.Helper()
	if err := e.Sandbox.RunGoCommand(e.Ctx, "", verb, args, true); err != nil {
		e.T.Fatal(err)
	}
}

// RunGoCommandInDir is like RunGoCommand, but executes in the given
// relative directory of the sandbox.
func (e *Env) RunGoCommandInDir(dir, verb string, args ...string) {
	e.T.Helper()
	if err := e.Sandbox.RunGoCommand(e.Ctx, dir, verb, args, true); err != nil {
		e.T.Fatal(err)
	}
}

// GoVersion checks the version of the go command.
// It returns the X in Go 1.X.
func (e *Env) GoVersion() int {
	e.T.Helper()
	v, err := e.Sandbox.GoVersion(e.Ctx)
	if err != nil {
		e.T.Fatal(err)
	}
	return v
}

// DumpGoSum prints the correct go.sum contents for dir in txtar format,
// for use in creating regtests.
func (e *Env) DumpGoSum(dir string) {
	e.T.Helper()

	if err := e.Sandbox.RunGoCommand(e.Ctx, dir, "list", []string{"-mod=mod", "..."}, true); err != nil {
		e.T.Fatal(err)
	}
	sumFile := path.Join(dir, "/go.sum")
	e.T.Log("\n\n-- " + sumFile + " --\n" + e.ReadWorkspaceFile(sumFile))
	e.T.Fatal("see contents above")
}

// CheckForFileChanges triggers a manual poll of the workspace for any file
// changes since creation, or since last polling. It is a workaround for the
// lack of true file watching support in the fake workspace.
func (e *Env) CheckForFileChanges() {
	e.T.Helper()
	if err := e.Sandbox.Workdir.CheckForFileChanges(e.Ctx); err != nil {
		e.T.Fatal(err)
	}
}

// CodeLens calls textDocument/codeLens for the given path, calling t.Fatal on
// any error.
func (e *Env) CodeLens(path string) []protocol.CodeLens {
	e.T.Helper()
	lens, err := e.Editor.CodeLens(e.Ctx, path)
	if err != nil {
		e.T.Fatal(err)
	}
	return lens
}

// ExecuteCodeLensCommand executes the command for the code lens matching the
// given command name.
func (e *Env) ExecuteCodeLensCommand(path string, cmd command.Command, result interface{}) {
	e.T.Helper()
	lenses := e.CodeLens(path)
	var lens protocol.CodeLens
	var found bool
	for _, l := range lenses {
		if l.Command.Command == cmd.ID() {
			lens = l
			found = true
		}
	}
	if !found {
		e.T.Fatalf("found no command with the ID %s", cmd.ID())
	}
	e.ExecuteCommand(&protocol.ExecuteCommandParams{
		Command:   lens.Command.Command,
		Arguments: lens.Command.Arguments,
	}, result)
}

func (e *Env) ExecuteCommand(params *protocol.ExecuteCommandParams, result interface{}) {
	e.T.Helper()
	response, err := e.Editor.ExecuteCommand(e.Ctx, params)
	if err != nil {
		e.T.Fatal(err)
	}
	if result == nil {
		return
	}
	// Hack: The result of an executeCommand request will be unmarshaled into
	// maps. Re-marshal and unmarshal into the type we expect.
	//
	// This could be improved by generating a jsonrpc2 command client from the
	// command.Interface, but that should only be done if we're consolidating
	// this part of the tsprotocol generation.
	data, err := json.Marshal(response)
	if err != nil {
		e.T.Fatal(err)
	}
	if err := json.Unmarshal(data, result); err != nil {
		e.T.Fatal(err)
	}
}

// InlayHints calls textDocument/inlayHints for the given path, calling t.Fatal on
// any error.
func (e *Env) InlayHints(path string) []protocol.InlayHint {
	e.T.Helper()
	hints, err := e.Editor.InlayHint(e.Ctx, path)
	if err != nil {
		e.T.Fatal(err)
	}
	return hints
}

// Symbol calls workspace/symbol
func (e *Env) Symbol(query string) []protocol.SymbolInformation {
	e.T.Helper()
	ans, err := e.Editor.Symbols(e.Ctx, query)
	if err != nil {
		e.T.Fatal(err)
	}
	return ans
}

// References wraps Editor.References, calling t.Fatal on any error.
func (e *Env) References(loc protocol.Location) []protocol.Location {
	e.T.Helper()
	locations, err := e.Editor.References(e.Ctx, loc)
	if err != nil {
		e.T.Fatal(err)
	}
	return locations
}

// Rename wraps Editor.Rename, calling t.Fatal on any error.
func (e *Env) Rename(loc protocol.Location, newName string) {
	e.T.Helper()
	if err := e.Editor.Rename(e.Ctx, loc, newName); err != nil {
		e.T.Fatal(err)
	}
}

// Implementations wraps Editor.Implementations, calling t.Fatal on any error.
func (e *Env) Implementations(loc protocol.Location) []protocol.Location {
	e.T.Helper()
	locations, err := e.Editor.Implementations(e.Ctx, loc)
	if err != nil {
		e.T.Fatal(err)
	}
	return locations
}

// RenameFile wraps Editor.RenameFile, calling t.Fatal on any error.
func (e *Env) RenameFile(oldPath, newPath string) {
	e.T.Helper()
	if err := e.Editor.RenameFile(e.Ctx, oldPath, newPath); err != nil {
		e.T.Fatal(err)
	}
}

// SignatureHelp wraps Editor.SignatureHelp, calling t.Fatal on error
func (e *Env) SignatureHelp(loc protocol.Location) *protocol.SignatureHelp {
	e.T.Helper()
	sighelp, err := e.Editor.SignatureHelp(e.Ctx, loc)
	if err != nil {
		e.T.Fatal(err)
	}
	return sighelp
}

// Completion executes a completion request on the server.
func (e *Env) Completion(loc protocol.Location) *protocol.CompletionList {
	e.T.Helper()
	completions, err := e.Editor.Completion(e.Ctx, loc)
	if err != nil {
		e.T.Fatal(err)
	}
	return completions
}

// AcceptCompletion accepts a completion for the given item at the given
// position.
func (e *Env) AcceptCompletion(loc protocol.Location, item protocol.CompletionItem) {
	e.T.Helper()
	if err := e.Editor.AcceptCompletion(e.Ctx, loc, item); err != nil {
		e.T.Fatal(err)
	}
}

// CodeAction calls testDocument/codeAction for the given path, and calls
// t.Fatal if there are errors.
func (e *Env) CodeAction(path string, diagnostics []protocol.Diagnostic) []protocol.CodeAction {
	e.T.Helper()
	loc := protocol.Location{URI: e.Sandbox.Workdir.URI(path)} // no Range => whole file
	actions, err := e.Editor.CodeAction(e.Ctx, loc, diagnostics)
	if err != nil {
		e.T.Fatal(err)
	}
	return actions
}

// ChangeConfiguration updates the editor config, calling t.Fatal on any error.
func (e *Env) ChangeConfiguration(newConfig fake.EditorConfig) {
	e.T.Helper()
	if err := e.Editor.ChangeConfiguration(e.Ctx, newConfig); err != nil {
		e.T.Fatal(err)
	}
}

// ChangeWorkspaceFolders updates the editor workspace folders, calling t.Fatal
// on any error.
func (e *Env) ChangeWorkspaceFolders(newFolders ...string) {
	e.T.Helper()
	if err := e.Editor.ChangeWorkspaceFolders(e.Ctx, newFolders); err != nil {
		e.T.Fatal(err)
	}
}

// Close shuts down the editor session and cleans up the sandbox directory,
// calling t.Error on any error.
func (e *Env) Close() {
	ctx := xcontext.Detach(e.Ctx)
	if err := e.Editor.Close(ctx); err != nil {
		e.T.Errorf("closing editor: %v", err)
	}
	if err := e.Sandbox.Close(); err != nil {
		e.T.Errorf("cleaning up sandbox: %v", err)
	}
}
