/* lib.rs
 *
 * Copyright 2026 Christian Kruse
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

pub mod app_window;
pub mod askpass;
pub mod branch_info_box;
pub mod changed_file_row;
pub mod clone_dialog;
pub mod clone_progress_dialog;
pub mod commit_log_view;
pub mod commit_message_dialog;
pub mod commit_search_bar;
pub mod config;
pub mod confirm_dialog;
pub mod create_tag_dialog;
pub mod credential_dialog;
pub mod credentials;
pub mod diff_list_model;
pub mod diff_styling;
pub mod diff_view;
pub mod file_diff_row;
pub mod git;
pub mod macos;
pub mod menus;
pub mod merge_dialog;
pub mod portal;
pub mod preferences;
pub mod pull_dialog;
pub mod push_dialog;
pub mod release_notes;
pub mod release_notes_dialog;
pub mod repo_row;
pub mod repo_view;
pub mod repository;
pub mod search_query;
pub mod select_remote_dialog;
pub mod start_screen;
pub mod stash_switch_dialog;
pub mod stashes_view;
pub mod tag_info_box;
pub mod tag_list_view;
pub mod text_prompt_dialog;
pub mod tree_list_view;
pub mod tree_node;
pub mod ui_helpers;
pub mod update_check;
pub mod window;
pub mod window_content;
pub mod working_copy_view;
pub mod wrapping;

use std::path::PathBuf;
use std::sync::Mutex;

use config::GETTEXT_PACKAGE;
use gettextrs::{bind_textdomain_codeset, bindtextdomain, textdomain};
use relm4::gtk::gio;
use relm4::gtk::gio::prelude::*;
use relm4::prelude::*;
use window::{APP_BROKER, App, AppMsg};

pub static PENDING_OPEN_PATH: Mutex<Option<PathBuf>> = Mutex::new(None);

pub fn run() {
    let (pkgdatadir, localedir) = macos::bundle_paths();

    tracing_subscriber::fmt::init();

    bindtextdomain(GETTEXT_PACKAGE, &localedir).expect("Unable to bind the text domain");
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8").expect("Unable to set the text domain encoding");
    textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain");

    let resources = gio::Resource::load(pkgdatadir.join("gitte.gresource")).expect("Could not load resources");
    gio::resources_register(&resources);

    let _askpass_guard = askpass::server::start();

    let gtk_app = relm4::main_adw_application();
    gtk_app.set_application_id(Some("de.wwwtech.gitte"));
    gtk_app.set_flags(gtk_app.flags() | gio::ApplicationFlags::HANDLES_COMMAND_LINE);

    gtk_app.connect_startup(|_| {
        if let Some(display) = relm4::gtk::gdk::Display::default() {
            let icon_theme = relm4::gtk::IconTheme::for_display(&display);
            icon_theme.add_resource_path("/de/wwwtech/gitte/icons");

            if icon_theme.theme_name() == "hicolor" || icon_theme.theme_name().is_empty() {
                icon_theme.set_theme_name(Some("Adwaita"));
            }
        }
    });

    gtk_app.connect_command_line(|app, cmdline| {
        let args = cmdline.arguments();
        let path_arg = args.iter().skip(1).find_map(|os| {
            let s = os.to_string_lossy();

            if s.starts_with('-') {
                None
            } else {
                Some(PathBuf::from(os))
            }
        });

        if let Some(mut p) = path_arg {
            if p.is_relative()
                && let Some(cwd) = cmdline.cwd()
            {
                p = cwd.join(p);
            }

            *PENDING_OPEN_PATH.lock().unwrap_or_else(|e| e.into_inner()) = Some(p.clone());
            APP_BROKER.send(AppMsg::OpenPath(p));
        }

        app.activate();
        0.into()
    });

    let app = RelmApp::from_app(gtk_app).with_broker(&APP_BROKER);
    app.run::<App>(());
}
