package main

import (
	"context"
	"crypto/ecdsa"
	"flag"
	"fmt"
	"log/slog"
	"net"
	"os"

	"koti.casa/numenor-labs/dsfx/shared/dcrypto"
	"koti.casa/numenor-labs/dsfx/shared/dlog"
	"koti.casa/numenor-labs/dsfx/shared/dnet"
)

func main() {
	ctx := context.Background()

	// ---------------------------------------------------------------------------
	// Logger

	opts := &slog.HandlerOptions{
		AddSource: false,
		Level:     slog.LevelDebug,
	}
	logger := slog.New(slog.NewTextHandler(os.Stdout, opts))

	// Everything in the application will attempt to use the logger in stored in
	// the context, but we also set the default with slog as a fallback. In cases
	// where the context is not available, or the context is not a child of the
	// context with the logger, the default logger will be used.
	slog.SetDefault(logger)
	ctx = dlog.WithContext(ctx, logger)

	// ---------------------------------------------------------------------------
	// Commands

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [command] [args]\n", os.Args[0])
		fmt.Fprintf(os.Stderr, "Commands:\n")
		fmt.Fprintf(os.Stderr, "  test <remote_addr>  Test the connection to the server\n")
		fmt.Fprintf(os.Stderr, "Flags:\n")
		flag.PrintDefaults()
	}

	flagKey := flag.String("key", "", "the path to the key file")

	flag.Parse()

	if *flagKey == "" {
		logger.ErrorContext(ctx, "private key path is required")
		os.Exit(1)
	}

	identity, err := dcrypto.LoadSigningKeyFromFile(*flagKey)
	if err != nil {
		logger.ErrorContext(ctx, "failed to load private key", slog.Any("error", err))
		os.Exit(1)
	}

	laddr := dnet.NewAddr(
		net.ParseIP("0.0.0.0"),
		0, // port 0 means any available port
		&identity.PublicKey,
	)

	logger.DebugContext(ctx, "using addr", slog.String("address", laddr.String()))

	switch flag.Arg(0) {
	case "test":
		raddrRaw := flag.Arg(1)
		if raddrRaw == "" {
			logger.ErrorContext(ctx, "no remote address provided")
			os.Exit(1)
		}
		testConnection(ctx, identity, laddr, raddrRaw)
	case "":
		logger.InfoContext(ctx, "no command provided")
		os.Exit(1)
	default:
		logger.InfoContext(ctx, "unknown command")
		os.Exit(1)
	}
}

func testConnection(ctx context.Context, identity *ecdsa.PrivateKey, laddr *dnet.Addr, raddrRaw string) {
	logger := dlog.FromContext(context.Background())

	raddr, err := dnet.ParseAddr(raddrRaw)
	if err != nil {
		logger.ErrorContext(ctx, "failed to parse server address", slog.Any("error", err))
		return
	}

	conn, err := dnet.Dial(ctx, identity, laddr, raddr)
	if err != nil {
		logger.ErrorContext(ctx, "failed to connect", slog.Any("error", err))
		return
	}
	defer conn.Close()
}