/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#include "dnc.h"
#include "common.h"
#include <string>
#include <vector>
#include <iostream>
#include <unistd.h>
#include <getopt.h>

#include <netinet/in.h>

struct dhtnc_params
{
    bool help {false};
    bool version {false};
    bool listen {false};
    std::string ip_add {};
    std::string bootstrap_ip {};
    std::string bootstrap_port {};
    in_port_t port {};
    dht::InfoHash peer_id {};
};

static const constexpr struct option long_options[]
    = {{"help", no_argument, nullptr, 'h'},
       {"version", no_argument, nullptr, 'v'},
       {"port", required_argument, nullptr, 'p'},
       {"ip", required_argument, nullptr, 'i'},
       {"listen", no_argument, nullptr, 'l'},
       {"bootstrap_ip", required_argument, nullptr, 'b'},
       {"bootstrap_port", required_argument, nullptr, 'P'},
       {nullptr, 0, nullptr, 0}};

dhtnc_params
parse_args(int argc, char** argv)
{
    dhtnc_params params;
    int opt;
    while ((opt = getopt_long(argc, argv, "hvp:i:", long_options, nullptr)) != -1) {
        switch (opt) {
        case 'h':
            params.help = true;
            break;
        case 'v':
            params.version = true;
            break;
        case 'p':
            params.port = std::stoi(optarg);
            break;
        case 'i':
            params.ip_add = optarg;
            break;
        case 'l':
            params.listen = true;
            break;
        case 'b':
            params.bootstrap_ip = optarg;
            break;
        case 'P':
            params.bootstrap_port = optarg;
            break;
        default:
            std::cerr << "Invalid option" << std::endl;
            exit(EXIT_FAILURE);
        }
    }

    // If not listening, the peer_id argument is required
    if (!params.listen) {
        if (optind < argc) {
            params.peer_id = dht::InfoHash(argv[optind]);
            optind++; // Move to the next argument
        } else {
            std::cerr << "Error: Missing peer_id argument.\n";
            exit(EXIT_FAILURE);
        }
    }

    // default values
    if (params.port == 0)
        params.port = 22;
    if (params.ip_add.empty())
        params.ip_add = "127.0.0.1";
    if (params.bootstrap_ip.empty())
        params.bootstrap_ip = "bootstrap.jami.net";
    if (params.bootstrap_port.empty())
        params.bootstrap_port = "4222";
    return params;
}

static void
setSipLogLevel()
{
    char* envvar = getenv("SIPLOGLEVEL");

    int level = 0;

    if (envvar != nullptr) {
        level = std::stoi(envvar);

        // From 0 (min) to 6 (max)
        level = std::max(0, std::min(level, 6));
    }

    pj_log_set_level(level);
    pj_log_set_log_func([](int level, const char* data, int /*len*/) {
    });
}

int
main(int argc, char** argv)
{
    setSipLogLevel();
    auto params = parse_args(argc, argv);

    std::unique_ptr<dhtnet::Dnc> dhtnc;
    if (params.listen) {
        auto identity = dhtnet::loadIdentity(true);
        // create dnc instance
        dhtnc = std::make_unique<dhtnet::Dnc>(identity, params.bootstrap_ip, params.bootstrap_port);
        fmt::print("DhtNC 1.1\n");
        fmt::print("Loaded identity: {}\n", identity.second->getId());
    } else {
        auto identity = dhtnet::loadIdentity(false);
        dhtnc = std::make_unique<dhtnet::Dnc>(identity,
                                              params.bootstrap_ip,
                                              params.bootstrap_port,
                                              params.peer_id,
                                              params.port,
                                              params.ip_add);
        fmt::print("DhtNC 1.0\n");
        fmt::print("Loaded identity: {}\n", identity.second->getId());
    }
    dhtnc->run();
}
