// Copyright 2021 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 lsprpc

import (
	"context"
	"fmt"
	"io"
	"net"
	"os"
	"time"

	exec "golang.org/x/sys/execabs"
	"golang.org/x/tools/internal/event"
)

// AutoNetwork is the pseudo network type used to signal that gopls should use
// automatic discovery to resolve a remote address.
const AutoNetwork = "auto"

// An AutoDialer is a jsonrpc2 dialer that understands the 'auto' network.
type AutoDialer struct {
	network, addr string // the 'real' network and address
	isAuto        bool   // whether the server is on the 'auto' network

	executable string
	argFunc    func(network, addr string) []string
}

func NewAutoDialer(rawAddr string, argFunc func(network, addr string) []string) (*AutoDialer, error) {
	d := AutoDialer{
		argFunc: argFunc,
	}
	d.network, d.addr = ParseAddr(rawAddr)
	if d.network == AutoNetwork {
		d.isAuto = true
		bin, err := os.Executable()
		if err != nil {
			return nil, fmt.Errorf("getting executable: %w", err)
		}
		d.executable = bin
		d.network, d.addr = autoNetworkAddress(bin, d.addr)
	}
	return &d, nil
}

// Dial implements the jsonrpc2.Dialer interface.
func (d *AutoDialer) Dial(ctx context.Context) (io.ReadWriteCloser, error) {
	conn, err := d.dialNet(ctx)
	return conn, err
}

// TODO(rFindley): remove this once we no longer need to integrate with v1 of
// the jsonrpc2 package.
func (d *AutoDialer) dialNet(ctx context.Context) (net.Conn, error) {
	// Attempt to verify that we own the remote. This is imperfect, but if we can
	// determine that the remote is owned by a different user, we should fail.
	ok, err := verifyRemoteOwnership(d.network, d.addr)
	if err != nil {
		// If the ownership check itself failed, we fail open but log an error to
		// the user.
		event.Error(ctx, "unable to check daemon socket owner, failing open", err)
	} else if !ok {
		// We successfully checked that the socket is not owned by us, we fail
		// closed.
		return nil, fmt.Errorf("socket %q is owned by a different user", d.addr)
	}
	const dialTimeout = 1 * time.Second
	// Try dialing our remote once, in case it is already running.
	netConn, err := net.DialTimeout(d.network, d.addr, dialTimeout)
	if err == nil {
		return netConn, nil
	}
	if d.isAuto && d.argFunc != nil {
		if d.network == "unix" {
			// Sometimes the socketfile isn't properly cleaned up when the server
			// shuts down. Since we have already tried and failed to dial this
			// address, it should *usually* be safe to remove the socket before
			// binding to the address.
			// TODO(rfindley): there is probably a race here if multiple server
			// instances are simultaneously starting up.
			if _, err := os.Stat(d.addr); err == nil {
				if err := os.Remove(d.addr); err != nil {
					return nil, fmt.Errorf("removing remote socket file: %w", err)
				}
			}
		}
		args := d.argFunc(d.network, d.addr)
		cmd := exec.Command(d.executable, args...)
		if err := runRemote(cmd); err != nil {
			return nil, err
		}
	}

	const retries = 5
	// It can take some time for the newly started server to bind to our address,
	// so we retry for a bit.
	for retry := 0; retry < retries; retry++ {
		startDial := time.Now()
		netConn, err = net.DialTimeout(d.network, d.addr, dialTimeout)
		if err == nil {
			return netConn, nil
		}
		event.Log(ctx, fmt.Sprintf("failed attempt #%d to connect to remote: %v\n", retry+2, err))
		// In case our failure was a fast-failure, ensure we wait at least
		// f.dialTimeout before trying again.
		if retry != retries-1 {
			time.Sleep(dialTimeout - time.Since(startDial))
		}
	}
	return nil, fmt.Errorf("dialing remote: %w", err)
}
