// Copyright 2018 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"
	"io"
	"log"
	"net"
	"os"
	"path/filepath"
	"strings"
	"time"

	"golang.org/x/tools/internal/jsonrpc2"
	"golang.org/x/tools/internal/lsp"
	"golang.org/x/tools/internal/tool"
)

// Serve is a struct that exposes the configurable parts of the LSP server as
// flags, in the right form for tool.Main to consume.
type Serve struct {
	Logfile string `flag:"logfile" help:"filename to log to. if value is \"auto\", then logging to a default output file is enabled"`
	Mode    string `flag:"mode" help:"no effect"`
	Port    int    `flag:"port" help:"port on which to run gopls for debugging purposes"`
	Address string `flag:"listen" help:"address on which to listen for remote connections"`

	app *Application
}

func (s *Serve) Name() string  { return "serve" }
func (s *Serve) Usage() string { return "" }
func (s *Serve) ShortHelp() string {
	return "run a server for Go code using the Language Server Protocol"
}
func (s *Serve) DetailedHelp(f *flag.FlagSet) {
	fmt.Fprint(f.Output(), `
The server communicates using JSONRPC2 on stdin and stdout, and is intended to be run directly as
a child of an editor process.

gopls server flags are:
`)
	f.PrintDefaults()
}

// Run configures a server based on the flags, and then runs it.
// It blocks until the server shuts down.
func (s *Serve) Run(ctx context.Context, args ...string) error {
	if len(args) > 0 {
		return tool.CommandLineErrorf("server does not take arguments, got %v", args)
	}
	out := os.Stderr
	if s.Logfile != "" {
		filename := s.Logfile
		if filename == "auto" {
			filename = filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.log", os.Getpid()))
		}
		f, err := os.Create(filename)
		if err != nil {
			return fmt.Errorf("Unable to create log file: %v", err)
		}
		defer f.Close()
		log.SetOutput(io.MultiWriter(os.Stderr, f))
		out = f
	}
	if s.app.Remote != "" {
		return s.forward()
	}
	logger := func(direction jsonrpc2.Direction, id *jsonrpc2.ID, elapsed time.Duration, method string, payload *json.RawMessage, err *jsonrpc2.Error) {
		const eol = "\r\n\r\n\r\n"
		if err != nil {
			fmt.Fprintf(out, "[Error - %v] %s %s%s %v%s", time.Now().Format("3:04:05 PM"),
				direction, method, id, err, eol)
			return
		}
		outx := new(strings.Builder)
		fmt.Fprintf(outx, "[Trace - %v] ", time.Now().Format("3:04:05 PM"))
		switch direction {
		case jsonrpc2.Send:
			fmt.Fprint(outx, "Received ")
		case jsonrpc2.Receive:
			fmt.Fprint(outx, "Sending ")
		}
		switch {
		case id == nil:
			fmt.Fprint(outx, "notification ")
		case elapsed >= 0:
			fmt.Fprint(outx, "response ")
		default:
			fmt.Fprint(outx, "request ")
		}
		fmt.Fprintf(outx, "'%s", method)
		switch {
		case id == nil:
			// do nothing
		case id.Name != "":
			fmt.Fprintf(outx, " - (%s)", id.Name)
		default:
			fmt.Fprintf(outx, " - (%d)", id.Number)
		}
		fmt.Fprint(outx, "'")
		if elapsed >= 0 {
			msec := int(elapsed.Round(time.Millisecond) / time.Millisecond)
			fmt.Fprintf(outx, " in %dms", msec)
		}
		params := "null"
		if payload != nil {
			params = string(*payload)
		}
		if params == "null" {
			params = "{}"
		}
		fmt.Fprintf(outx, ".\r\nParams: %s%s", params, eol)
		fmt.Fprintf(out, "%s", outx.String())
	}
	// For debugging purposes only.
	if s.Address != "" {
		return lsp.RunServerOnAddress(ctx, s.Address, logger)
	}
	if s.Port != 0 {
		return lsp.RunServerOnPort(ctx, s.Port, logger)
	}
	stream := jsonrpc2.NewHeaderStream(os.Stdin, os.Stdout)
	return lsp.RunServer(ctx, stream, logger)
}

func (s *Serve) forward() error {
	conn, err := net.Dial("tcp", s.app.Remote)
	if err != nil {
		return err
	}
	errc := make(chan error)

	go func(conn net.Conn) {
		_, err := io.Copy(conn, os.Stdin)
		errc <- err
	}(conn)

	go func(conn net.Conn) {
		_, err := io.Copy(os.Stdout, conn)
		errc <- err
	}(conn)

	return <-errc
}
