// 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"
	"os"
	"strings"
	"testing"

	"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) {
	os.Exit(Main(m))
}

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), // 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.String(),
		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
}
