// 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 servertest provides utilities for running tests against a remote LSP
// server.
package servertest

import (
	"context"
	"fmt"
	"net"
	"strings"
	"sync"

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

// Connector is the interface used to connect to a server.
type Connector interface {
	Connect(context.Context) jsonrpc2.Conn
}

// TCPServer is a helper for executing tests against a remote jsonrpc2
// connection. Once initialized, its Addr field may be used to connect a
// jsonrpc2 client.
type TCPServer struct {
	*connList

	Addr string

	ln     net.Listener
	framer jsonrpc2.Framer
}

// NewTCPServer returns a new test server listening on local tcp port and
// serving incoming jsonrpc2 streams using the provided stream server. It
// panics on any error.
func NewTCPServer(ctx context.Context, server jsonrpc2.StreamServer, framer jsonrpc2.Framer) *TCPServer {
	ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		panic(fmt.Sprintf("servertest: failed to listen: %v", err))
	}
	if framer == nil {
		framer = jsonrpc2.NewHeaderStream
	}
	go jsonrpc2.Serve(ctx, ln, server, 0)
	return &TCPServer{Addr: ln.Addr().String(), ln: ln, framer: framer, connList: &connList{}}
}

// Connect dials the test server and returns a jsonrpc2 Connection that is
// ready for use.
func (s *TCPServer) Connect(ctx context.Context) jsonrpc2.Conn {
	netConn, err := net.Dial("tcp", s.Addr)
	if err != nil {
		panic(fmt.Sprintf("servertest: failed to connect to test instance: %v", err))
	}
	conn := jsonrpc2.NewConn(s.framer(netConn))
	s.add(conn)
	return conn
}

// PipeServer is a test server that handles connections over io.Pipes.
type PipeServer struct {
	*connList
	server jsonrpc2.StreamServer
	framer jsonrpc2.Framer
}

// NewPipeServer returns a test server that can be connected to via io.Pipes.
func NewPipeServer(ctx context.Context, server jsonrpc2.StreamServer, framer jsonrpc2.Framer) *PipeServer {
	if framer == nil {
		framer = jsonrpc2.NewRawStream
	}
	return &PipeServer{server: server, framer: framer, connList: &connList{}}
}

// Connect creates new io.Pipes and binds them to the underlying StreamServer.
func (s *PipeServer) Connect(ctx context.Context) jsonrpc2.Conn {
	sPipe, cPipe := net.Pipe()
	serverStream := s.framer(sPipe)
	serverConn := jsonrpc2.NewConn(serverStream)
	s.add(serverConn)
	go s.server.ServeStream(ctx, serverConn)

	clientStream := s.framer(cPipe)
	clientConn := jsonrpc2.NewConn(clientStream)
	s.add(clientConn)
	return clientConn
}

// connList tracks closers to run when a testserver is closed.  This is a
// convenience, so that callers don't have to worry about closing each
// connection.
type connList struct {
	mu    sync.Mutex
	conns []jsonrpc2.Conn
}

func (l *connList) add(conn jsonrpc2.Conn) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.conns = append(l.conns, conn)
}

func (l *connList) Close() error {
	l.mu.Lock()
	defer l.mu.Unlock()
	var errmsgs []string
	for _, conn := range l.conns {
		if err := conn.Close(); err != nil {
			errmsgs = append(errmsgs, err.Error())
		}
	}
	if len(errmsgs) > 0 {
		return fmt.Errorf("closing errors:\n%s", strings.Join(errmsgs, "\n"))
	}
	return nil
}
