package main

import (
	"context"

	"github.com/urfave/cli/v3"

	"git.maze.io/go/ham/protocol/aprs/aprsis"

	"git.maze.io/ham/hamview"
	"git.maze.io/ham/hamview/cmd"
)

type aprsisConfig struct {
	Broker   hamview.BrokerConfig `yaml:"broker"`
	Receiver hamview.APRSISConfig `yaml:"receiver"`
	Include  []string             `yaml:"include"`
}

func (config *aprsisConfig) Includes() []string {
	includes := config.Include
	config.Include = nil
	return includes
}

func runAPRSIS(ctx context.Context, command *cli.Command) error {
	var config = aprsisConfig{
		Receiver: hamview.APRSISConfig{
			Listen: hamview.DefaultAPRSISListen,
			Server: hamview.DefaultAPRSISServer,
		},
	}
	if err := cmd.Load(logger, command.String(cmd.FlagConfig), &config); err != nil {
		return err
	}

	logger.Infof("receiver: starting APRS-IS proxy on tcp://%s to tcp://%s",
		config.Receiver.Listen,
		config.Receiver.Server)
	proxy, err := aprsis.NewProxy(config.Receiver.Listen, config.Receiver.Server)
	if err != nil {
		return err
	}

	proxy.OnClient = func(callsign string, client *aprsis.ProxyClient) {
		go receiveAPRSIS(&config.Broker, callsign, client)
	}

	return waitForInterrupt()
}

func receiveAPRSIS(config *hamview.BrokerConfig, callsign string, client *aprsis.ProxyClient) {
	defer func() { _ = client.Close() }()

	broker, err := hamview.NewBroker(config)
	if err != nil {
		logger.Errorf("receiver: can't setup to broker: %v", err)
		return
	}
	defer func() { _ = broker.Close() }()

	info := client.Info() // TODO: enrich info from config?

	if err = broker.StartRadio("aprs", info); err != nil {
		logger.Fatalf("receiver: can't start broker: %v", err)
		return
	}

	logger.Infof("receiver: start receiving packets from station: %s", callsign)
	for packet := range client.RawPackets() {
		logger.Debugf("aprs packet: %#+v", packet)
		if err := broker.PublishPacket("aprs/packet", packet); err != nil {
			logger.Error(err)
		}
	}
	logger.Infof("receiver: stopped receiving packets from station: %s", callsign)
}
