// Copyright 2022 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 debug

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
	"strings"
	"testing"

	"golang.org/x/tools/gopls/internal/hooks"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/protocol/command"
	. "golang.org/x/tools/gopls/internal/test/integration"
	"golang.org/x/tools/gopls/internal/util/bug"
)

func TestMain(m *testing.M) {
	Main(m, hooks.Options)
}

func TestBugNotification(t *testing.T) {
	// Verify that a properly configured session gets notified of a bug on the
	// server.
	WithOptions(
		Modes(Default), // must be in-process to receive the bug report below
		Settings{"showBugReports": true},
	).Run(t, "", func(t *testing.T, env *Env) {
		const desc = "got a bug"
		bug.Report(desc)
		env.Await(ShownMessage(desc))
	})
}

// TestStartDebugging executes a gopls.start_debugging command to
// start the internal web server.
func TestStartDebugging(t *testing.T) {
	WithOptions(
		Modes(Default|Experimental), // doesn't work in Forwarded mode
	).Run(t, "", func(t *testing.T, env *Env) {
		// Start a debugging server.
		res, err := startDebugging(env.Ctx, env.Editor.Server, &command.DebuggingArgs{
			Addr: "", // any free port
		})
		if err != nil {
			t.Fatalf("startDebugging: %v", err)
		}

		// Assert that the server requested that the
		// client show the debug page in a browser.
		debugURL := res.URLs[0]
		env.Await(ShownDocument(debugURL))

		// Send a request to the debug server and ensure it responds.
		resp, err := http.Get(debugURL)
		if err != nil {
			t.Fatal(err)
		}
		defer resp.Body.Close()
		data, err := io.ReadAll(resp.Body)
		if err != nil {
			t.Fatalf("reading HTTP response body: %v", err)
		}
		const want = "<title>Gopls"
		if !strings.Contains(string(data), want) {
			t.Errorf("GET %s response does not contain %q: <<%s>>", debugURL, want, data)
		}
	})
}

// startDebugging starts a debugging server.
// TODO(adonovan): move into command package?
func startDebugging(ctx context.Context, server protocol.Server, args *command.DebuggingArgs) (*command.DebuggingResult, error) {
	rawArgs, err := command.MarshalArgs(args)
	if err != nil {
		return nil, err
	}
	res0, err := server.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{
		Command:   command.StartDebugging.ID(),
		Arguments: rawArgs,
	})
	if err != nil {
		return nil, err
	}
	// res0 is the result of a schemaless (map[string]any) JSON decoding.
	// Re-encode and decode into the correct Go struct type.
	// TODO(adonovan): fix (*serverDispatcher).ExecuteCommand.
	data, err := json.Marshal(res0)
	if err != nil {
		return nil, err
	}
	var res *command.DebuggingResult
	if err := json.Unmarshal(data, &res); err != nil {
		return nil, err
	}
	return res, nil
}
