package network

import (
	"context"
	"crypto/ed25519"
	"net"

	"koti.casa/numenor-labs/dsfx/internal/lib/handshake"
	"koti.casa/numenor-labs/dsfx/internal/lib/logging"
)

// Dial ...
func Dial(
	ctx context.Context,
	identity ed25519.PrivateKey,
	laddr *Addr,
	raddr *Addr,
) (*Conn, error) {
	conn, err := net.DialTCP("tcp", laddr.TCPAddr(), raddr.TCPAddr())
	if err != nil {
		return nil, err
	}

	sessionKey, err := handshake.Initiate(ctx, conn, identity, raddr.PublicKey())
	if err != nil {
		return nil, err
	}

	return NewConn(conn, sessionKey, laddr.PublicKey(), raddr.PublicKey()), nil
}

// Listen ...
func Listen(
	ctx context.Context,
	identity ed25519.PrivateKey,
	laddr *Addr,
) (net.Listener, error) {
	tcpListener, err := net.ListenTCP("tcp", laddr.TCPAddr())
	if err != nil {
		return nil, err
	}

	logger := logging.FromContext(ctx)

	return &Listener{logger, tcpListener, identity}, nil
}