#include "mainwindow.h"
#include "config.h"

#include <QApplication>
#include <QCommandLineParser>
#include <cstdio>
#include <stdexcept>

/**
 * Parse a "label@host:port[/group:dataport]" positional argument into a SourceConfig.
 * The optional /group:dataport suffix enables multicast mode.
 * Returns false and leaves sc unchanged on parse error.
 */
static bool parseSourceArg(const QString& arg, SourceConfig& sc)
{
    // Split off optional multicast suffix after '/'
    QString base = arg;
    QString mcastPart;
    int slash = arg.indexOf('/');
    if (slash >= 0) {
        base      = arg.left(slash);
        mcastPart = arg.mid(slash + 1);
    }

    // label@host:port
    int at = base.indexOf('@');
    if (at < 0) return false;
    sc.label = base.left(at).toStdString();
    QString hostport = base.mid(at + 1);
    int colon = hostport.lastIndexOf(':');
    if (colon < 0) return false;
    sc.host = hostport.left(colon).toStdString();
    bool ok = false;
    sc.port = static_cast<uint16_t>(hostport.mid(colon + 1).toUShort(&ok));
    if (!ok) return false;

    // Parse optional multicast suffix: group:dataport
    if (!mcastPart.isEmpty()) {
        int mc = mcastPart.lastIndexOf(':');
        if (mc >= 0) {
            sc.multicast_group = mcastPart.left(mc).toStdString();
            bool dp_ok = false;
            sc.data_port = static_cast<uint16_t>(mcastPart.mid(mc + 1).toUShort(&dp_ok));
            if (!dp_ok) sc.data_port = 0;
        } else {
            sc.multicast_group = mcastPart.toStdString();
            sc.data_port = 0;
        }
    }

    return true;
}

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    app.setApplicationName("daq_viewer");
    app.setApplicationVersion("1.0");
    app.setOrganizationName("MARTe2");

    QCommandLineParser parser;
    parser.setApplicationDescription(
        "DAQ Viewer — real-time MARTe2 UDPStreamer client\n"
        "\n"
        "Positional arguments can be:\n"
        "  <config.ini>                         INI config file\n"
        "  <label@host:port>                    Unicast source\n"
        "  <label@host:port/group:dataport>     Multicast source\n"
        "Examples:\n"
        "  Streamer@127.0.0.1:44500\n"
        "  MCast@192.168.1.10:44500/239.0.0.1:44501");
    parser.addHelpOption();
    parser.addVersionOption();
    parser.addPositionalArgument("sources",
        "INI config file  -or-  one or more label@host:port sources",
        "[config | label@host:port ...]");

    parser.process(app);

    AppConfig cfg;
    const QStringList posArgs = parser.positionalArguments();

    if (!posArgs.isEmpty()) {
        // If first argument looks like a file (no '@'), treat as INI
        SourceConfig probe;
        if (!parseSourceArg(posArgs[0], probe)) {
            // INI file
            try {
                cfg = parse_ini(posArgs[0].toStdString());
            } catch (const std::exception& e) {
                std::fprintf(stderr, "Config error: %s\n", e.what());
                return 1;
            }
        } else {
            // All positional args are label@host:port
            for (const QString& arg : posArgs) {
                SourceConfig sc;
                if (parseSourceArg(arg, sc)) {
                    cfg.sources.push_back(sc);
                } else {
                    std::fprintf(stderr,
                        "Warning: cannot parse source '%s' — expected label@host:port\n",
                        arg.toUtf8().constData());
                }
            }
        }
    }

    // Default source if nothing specified
    if (cfg.sources.empty()) {
        SourceConfig sc;
        sc.label = "Source";
        sc.host  = "localhost";
        sc.port  = 44500;
        cfg.sources.push_back(sc);
    }

    MainWindow win(cfg);
    win.show();
    return app.exec();
}
