// 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 cmd

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"

	"golang.org/x/tools/internal/lsp/command"
	"golang.org/x/tools/internal/lsp/lsprpc"
	errors "golang.org/x/xerrors"
)

type remote struct {
	subcommands

	// For backward compatibility, allow aliasing this command (it was previously
	// called 'inspect').
	//
	// TODO(rFindley): delete this after allowing some transition time in case
	//                 there were any users of 'inspect' (I suspect not).
	alias string
}

func newRemote(app *Application, alias string) *remote {
	return &remote{
		subcommands: subcommands{
			&listSessions{app: app},
			&startDebugging{app: app},
		},
		alias: alias,
	}
}

func (r *remote) Name() string {
	if r.alias != "" {
		return r.alias
	}
	return "remote"
}

func (r *remote) ShortHelp() string {
	short := "interact with the gopls daemon"
	if r.alias != "" {
		short += " (deprecated: use 'remote')"
	}
	return short
}

// listSessions is an inspect subcommand to list current sessions.
type listSessions struct {
	app *Application
}

func (c *listSessions) Name() string  { return "sessions" }
func (c *listSessions) Usage() string { return "" }
func (c *listSessions) ShortHelp() string {
	return "print information about current gopls sessions"
}

const listSessionsExamples = `
Examples:

1) list sessions for the default daemon:

$ gopls -remote=auto remote sessions
or just
$ gopls remote sessions

2) list sessions for a specific daemon:

$ gopls -remote=localhost:8082 remote sessions
`

func (c *listSessions) DetailedHelp(f *flag.FlagSet) {
	fmt.Fprint(f.Output(), listSessionsExamples)
	f.PrintDefaults()
}

func (c *listSessions) Run(ctx context.Context, args ...string) error {
	remote := c.app.Remote
	if remote == "" {
		remote = "auto"
	}
	state, err := lsprpc.QueryServerState(ctx, remote)
	if err != nil {
		return err
	}
	v, err := json.MarshalIndent(state, "", "\t")
	if err != nil {
		log.Fatal(err)
	}
	os.Stdout.Write(v)
	return nil
}

type startDebugging struct {
	app *Application
}

func (c *startDebugging) Name() string  { return "debug" }
func (c *startDebugging) Usage() string { return "[host:port]" }
func (c *startDebugging) ShortHelp() string {
	return "start the debug server"
}

const startDebuggingExamples = `
Examples:

1) start a debug server for the default daemon, on an arbitrary port:

$ gopls -remote=auto remote debug
or just
$ gopls remote debug

2) start for a specific daemon, on a specific port:

$ gopls -remote=localhost:8082 remote debug localhost:8083
`

func (c *startDebugging) DetailedHelp(f *flag.FlagSet) {
	fmt.Fprint(f.Output(), startDebuggingExamples)
	f.PrintDefaults()
}

func (c *startDebugging) Run(ctx context.Context, args ...string) error {
	if len(args) > 1 {
		fmt.Fprintln(os.Stderr, c.Usage())
		return errors.New("invalid usage")
	}
	remote := c.app.Remote
	if remote == "" {
		remote = "auto"
	}
	debugAddr := ""
	if len(args) > 0 {
		debugAddr = args[0]
	}
	debugArgs := command.DebuggingArgs{
		Addr: debugAddr,
	}
	var result command.DebuggingResult
	if err := lsprpc.ExecuteCommand(ctx, remote, command.StartDebugging.ID(), debugArgs, &result); err != nil {
		return err
	}
	if len(result.URLs) == 0 {
		return errors.New("no debugging URLs")
	}
	for _, url := range result.URLs {
		fmt.Printf("debugging on %s\n", url)
	}
	return nil
}
