// SPDX-FileCopyrightText: 2023 CELESTIFYX Team
// SPDX-License-Identifier: GPL-3.0-or-later

use std::{
    collections::HashSet,
    path::PathBuf
};

use crate::{
    error::AppError,
    app::App,

    ports::{
        Port,
        scan_all
    },

    repo::{
        Repo,
        RepoPaths,
        load_repos
    },

    runtime::{
        Runtime,
        load_mask_set
    },

    pkg::{
        REPO_LIST,
        INSTALLED_DB,
        MASK_FILE
    }
};

mod app;
mod error;
mod events;
mod pkg;
mod ports;
mod repo;
mod runtime;
mod ui;

fn main() -> () {
    if let Err(e) = run() {
        eprintln!("Error: {}", e);
        std::process::exit(1);
    }
}

fn run() -> Result<(), AppError> {
    if unsafe {
        libc::geteuid()
    } != 0 {
        return Err(AppError::NotRoot);
    }

    let repo_list_path:    PathBuf = PathBuf::from(REPO_LIST);
    let installed_db_path: PathBuf = PathBuf::from(INSTALLED_DB);
    let mask_file_path:    PathBuf = PathBuf::from(MASK_FILE);

    let paths: RepoPaths = RepoPaths {
        repo_list:    repo_list_path,
        installed_db: installed_db_path
    };

    let repos: Vec<Repo> = load_repos(&paths)?;

    if repos.is_empty() {
        return Err(AppError::NoRepos(paths.repo_list));
    }

    let mask: HashSet<String> = load_mask_set(&mask_file_path);
    let port_index: Vec<Port> = scan_all(&repos, &paths, &mask)?;

    if port_index.is_empty() {
        return Err(AppError::NoPorts);
    }

    let app: App = App::new(port_index);
    let mut rt: Runtime = Runtime::new(app, repos, paths)?;

    (&mut rt).run()?;
    Ok(())
}
