#include "backend.hpp"
#ifdef GLIB_ENABLED
#include <glib-object.h>
#endif
#include "data.h"
#include "thirdparty/CLI11.hpp"
std::map<std::string, UIBackend*> UIBackend::backends;
std::string UIBackend::get_id() {
    return "";
}
UIBackend *UIBackend::running_ui_backend = nullptr;
void UIBackend::init_playback() {
    if (multi_instance) {
        playback = new PlaybackInstance();
    } else {
        playback = Playback::Create(&daemon_found);
        if (playback == nullptr) {
            throw 1;
        }
    }
}
void UIBackend::init_libportal() {
#ifdef GLIB_ENABLED
    g_set_application_name("Looper");
#endif
}
void UIBackend::setup_playback_args() {
    if (speed_set) {
        playback->SetSpeed(new_speed);
    }
    if (tempo_set) {
        playback->SetTempo(new_tempo);
    }
    if (pitch_set) {
        playback->SetPitch(new_pitch);
    }
    if (args.size() > 0) {
        playback->Start(args[0]);
    }
    if (!daemon_found && playback->is_proxy()) {
        throw 0;
    }
}
bool UIBackend::parse_args(std::vector<std::string> realArgs, int argc, char **argv) {
    args = realArgs;
    CLI::App app{DESCRIPTION};
    std::string filename = "";
    app.allow_extras();
    auto speed_opt = app.add_option("-s,--speed", new_speed, "Set the initial speed of the playback.")->default_val(1.0);
    auto tempo_opt = app.add_option("-t,--tempo", new_tempo, "Set the initial tempo of the playback.")->default_val(1.0);
    auto pitch_opt = app.add_option("-p,--pitch", new_pitch, "Set the initial pitch of the playback.")->default_val(1.0);
    std::vector<CLI::Option*> options;
    options.push_back(speed_opt);
    options.push_back(tempo_opt);
    options.push_back(pitch_opt);
    if (allow_multi_instance()) {
        auto multi_instance_opt = app.add_flag<bool>("-m,--multi-instance", multi_instance, "Disables the DBus api to allow multiple instances.");
        options.push_back(multi_instance_opt);
    }
    try {
        app.parse(args);
    } catch (const CLI::ParseError &e) {
        throw app.exit(e);
    }
    args = app.remaining();
    
    speed_set = !speed_opt->empty();
    tempo_set = !tempo_opt->empty();
    pitch_set = !pitch_opt->empty();
    if (args.size() > 0) {
        return true;
    } else {
        for (auto opt : options) {
            if (!opt->empty()) {
                return true;
            }
        }
    }
    return false;
}
void UIBackend::init_dbus() {
    if (!multi_instance && !playback->is_proxy()) {
        dbus_api = DBusAPI::Create(playback);
    }
}
int UIBackend::run(std::vector<std::string> realArgs, int argc, char **argv) {
    init_libportal();
    parse_args(realArgs, argc, argv);
    init_playback();
    setup_playback_args();
    init_dbus();
    return 0;
}
void UIBackend::deinit_backends() {
    for (auto &kv : backends) {
        delete kv.second;
    }
    backends.clear();
}
UIBackend::~UIBackend() {
    if (dbus_api != nullptr) delete dbus_api;
    delete playback;
}
std::string UIBackend::get_name() {
    return "Unknown frontend";
}