// Copyright 2019 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 cmdtest contains the test suite for the command line behavior of gopls.
package cmdtest

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"io"
	"os"
	"sync"
	"testing"

	"golang.org/x/tools/internal/jsonrpc2/servertest"
	"golang.org/x/tools/internal/lsp/cache"
	"golang.org/x/tools/internal/lsp/cmd"
	"golang.org/x/tools/internal/lsp/debug"
	"golang.org/x/tools/internal/lsp/lsprpc"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/lsp/tests"
	"golang.org/x/tools/internal/span"
	"golang.org/x/tools/internal/tool"
)

type runner struct {
	data        *tests.Data
	ctx         context.Context
	options     func(*source.Options)
	normalizers []tests.Normalizer
	remote      string
}

func TestCommandLine(t *testing.T, testdata string, options func(*source.Options)) {
	// On Android, the testdata directory is not copied to the runner.
	if stat, err := os.Stat(testdata); err != nil || !stat.IsDir() {
		t.Skip("testdata directory not present")
	}
	tests.RunTests(t, testdata, false, func(t *testing.T, datum *tests.Data) {
		ctx := tests.Context(t)
		ts := NewTestServer(ctx, options)
		tests.Run(t, NewRunner(datum, ctx, ts.Addr, options), datum)
		cmd.CloseTestConnections(ctx)
	})
}

func NewTestServer(ctx context.Context, options func(*source.Options)) *servertest.TCPServer {
	ctx = debug.WithInstance(ctx, "", "")
	cache := cache.New(options)
	ss := lsprpc.NewStreamServer(cache, false)
	return servertest.NewTCPServer(ctx, ss, nil)
}

func NewRunner(data *tests.Data, ctx context.Context, remote string, options func(*source.Options)) *runner {
	return &runner{
		data:        data,
		ctx:         ctx,
		options:     options,
		normalizers: tests.CollectNormalizers(data.Exported),
		remote:      remote,
	}
}

func (r *runner) CodeLens(t *testing.T, uri span.URI, want []protocol.CodeLens) {
	//TODO: add command line completions tests when it works
}

func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	//TODO: add command line completions tests when it works
}

func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
	//TODO: add command line completions tests when it works
}

func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	//TODO: add command line completions tests when it works
}

func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	//TODO: add command line completions tests when it works
}

func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	//TODO: add command line completions tests when it works
}

func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	//TODO: add command line completions tests when it works
}

func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
	//TODO: add command line completions tests when it works
}

func (r *runner) FunctionExtraction(t *testing.T, start span.Span, end span.Span) {
	//TODO: function extraction not supported on command line
}

func (r *runner) MethodExtraction(t *testing.T, start span.Span, end span.Span) {
	//TODO: function extraction not supported on command line
}

func (r *runner) AddImport(t *testing.T, uri span.URI, expectedImport string) {
	//TODO: import addition not supported on command line
}

func (r *runner) Hover(t *testing.T, spn span.Span, info string) {
	//TODO: hovering not supported on command line
}

func (r *runner) InlayHints(t *testing.T, spn span.Span) {
	// TODO: inlayHints not supported on command line
}

func (r *runner) runGoplsCmd(t testing.TB, args ...string) (string, string) {
	rStdout, wStdout, err := os.Pipe()
	if err != nil {
		t.Fatal(err)
	}
	oldStdout := os.Stdout
	rStderr, wStderr, err := os.Pipe()
	if err != nil {
		t.Fatal(err)
	}
	oldStderr := os.Stderr
	stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		io.Copy(stdout, rStdout)
		wg.Done()
	}()
	go func() {
		io.Copy(stderr, rStderr)
		wg.Done()
	}()
	os.Stdout, os.Stderr = wStdout, wStderr
	app := cmd.New("gopls-test", r.data.Config.Dir, r.data.Exported.Config.Env, r.options)
	remote := r.remote
	s := flag.NewFlagSet(app.Name(), flag.ExitOnError)
	err = tool.Run(tests.Context(t), s,
		app,
		append([]string{fmt.Sprintf("-remote=internal@%s", remote)}, args...))
	if err != nil {
		fmt.Fprint(os.Stderr, err)
	}
	wStdout.Close()
	wStderr.Close()
	wg.Wait()
	os.Stdout, os.Stderr = oldStdout, oldStderr
	rStdout.Close()
	rStderr.Close()
	return stdout.String(), stderr.String()
}

// NormalizeGoplsCmd runs the gopls command and normalizes its output.
func (r *runner) NormalizeGoplsCmd(t testing.TB, args ...string) (string, string) {
	stdout, stderr := r.runGoplsCmd(t, args...)
	return r.Normalize(stdout), r.Normalize(stderr)
}

func (r *runner) Normalize(s string) string {
	return tests.Normalize(s, r.normalizers)
}

func (r *runner) NormalizePrefix(s string) string {
	return tests.NormalizePrefix(s, r.normalizers)
}
