package socket

import (
	"crypto/rand"
	"encoding/hex"
	"errors"
	"io"
	"net"
	"os"
	"runtime"
	"sync"

	"github.com/sirupsen/logrus"
)

// EnvKey represents the well-known environment variable used to pass the
// plugin being executed the socket name it should listen on to coordinate with
// the host CLI.
const EnvKey = "DOCKER_CLI_PLUGIN_SOCKET"

// NewPluginServer creates a plugin server that listens on a new Unix domain
// socket. h is called for each new connection to the socket in a goroutine.
func NewPluginServer(h func(net.Conn)) (*PluginServer, error) {
	// Listen on a Unix socket, with the address being platform-dependent.
	// When a non-abstract address is used, Go will unlink(2) the socket
	// for us once the listener is closed, as documented in
	// [net.UnixListener.SetUnlinkOnClose].
	l, err := net.ListenUnix("unix", &net.UnixAddr{
		Name: socketName("docker_cli_" + randomID()),
		Net:  "unix",
	})
	if err != nil {
		return nil, err
	}
	logrus.Trace("Plugin server listening on ", l.Addr())

	if h == nil {
		h = func(net.Conn) {}
	}

	pl := &PluginServer{
		l: l,
		h: h,
	}

	go func() {
		defer pl.Close()
		for {
			err := pl.accept()
			if err != nil {
				return
			}
		}
	}()

	return pl, nil
}

type PluginServer struct {
	mu     sync.Mutex
	conns  []net.Conn
	l      *net.UnixListener
	h      func(net.Conn)
	closed bool
}

func (pl *PluginServer) accept() error {
	conn, err := pl.l.Accept()
	if err != nil {
		return err
	}

	pl.mu.Lock()
	defer pl.mu.Unlock()

	if pl.closed {
		// Handle potential race between Close and accept.
		conn.Close()
		return errors.New("plugin server is closed")
	}

	pl.conns = append(pl.conns, conn)

	go pl.h(conn)
	return nil
}

// Addr returns the [net.Addr] of the underlying [net.Listener].
func (pl *PluginServer) Addr() net.Addr {
	return pl.l.Addr()
}

// Close ensures that the server is no longer accepting new connections and
// closes all existing connections. Existing connections will receive [io.EOF].
//
// The error value is that of the underlying [net.Listener.Close] call.
func (pl *PluginServer) Close() error {
	if pl == nil {
		return nil
	}
	logrus.Trace("Closing plugin server")
	// Close connections first to ensure the connections get io.EOF instead
	// of a connection reset.
	pl.closeAllConns()

	// Try to ensure that any active connections have a chance to receive
	// io.EOF.
	runtime.Gosched()

	return pl.l.Close()
}

func (pl *PluginServer) closeAllConns() {
	pl.mu.Lock()
	defer pl.mu.Unlock()

	if pl.closed {
		return
	}

	// Prevent new connections from being accepted.
	pl.closed = true

	for _, conn := range pl.conns {
		conn.Close()
	}

	pl.conns = nil
}

func randomID() string {
	b := make([]byte, 16)
	if _, err := rand.Read(b); err != nil {
		panic(err) // This shouldn't happen
	}
	return hex.EncodeToString(b)
}

// ConnectAndWait connects to the socket passed via well-known env var,
// if present, and attempts to read from it until it receives an EOF, at which
// point cb is called.
func ConnectAndWait(cb func()) {
	socketAddr, ok := os.LookupEnv(EnvKey)
	if !ok {
		// if a plugin compiled against a more recent version of docker/cli
		// is executed by an older CLI binary, ignore missing environment
		// variable and behave as usual
		return
	}
	addr, err := net.ResolveUnixAddr("unix", socketAddr)
	if err != nil {
		return
	}
	conn, err := net.DialUnix("unix", nil, addr)
	if err != nil {
		return
	}

	go func() {
		b := make([]byte, 1)
		for {
			_, err := conn.Read(b)
			if errors.Is(err, io.EOF) {
				cb()
				return
			}
		}
	}()
}
