use include_dir::{include_dir, Dir};
use std::path::Path;
use winit::platform::android::activity::AndroidApp;

static GAME_ASSETS: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/../assets");
static BASE_MOD: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/../base_mod");
const ASSET_MARKER: &str = ".egregoria-assets-android-v2";

pub fn initialize_android(app: &AndroidApp) {
    android_logger::init_once(
        android_logger::Config::default()
            .with_tag("Egregoria")
            .with_max_level(log::LevelFilter::Info),
    );
    std::panic::set_hook(Box::new(|panic| log::error!("panic: {panic}")));

    let data_dir = app
        .internal_data_path()
        .expect("Android did not provide an internal data directory");
    std::fs::create_dir_all(&data_dir).expect("Failed to create Android data directory");
    std::env::set_current_dir(&data_dir).expect("Failed to enter Android data directory");

    let marker = data_dir.join(ASSET_MARKER);
    if !marker.exists() {
        let asset_dir = data_dir.join("assets");
        extract_dir(&GAME_ASSETS, &asset_dir);
        let base_mod_dir = data_dir.join("base_mod");
        extract_dir(&BASE_MOD, &base_mod_dir);
        std::fs::write(marker, include_str!("../../VERSION"))
            .expect("Failed to write Android asset marker");
    }

    for dir in [
        "world",
        "config",
        "logs",
        "screenshots",
        "assets/generated/building_icons",
    ] {
        std::fs::create_dir_all(data_dir.join(dir))
            .unwrap_or_else(|e| panic!("Failed to create {dir}: {e}"));
    }

    log::info!("Android data directory: {}", data_dir.display());
}

fn extract_dir(dir: &Dir<'_>, destination: &Path) {
    std::fs::create_dir_all(destination).expect("Failed to create embedded asset directory");

    for file in dir.files() {
        let name = file
            .path()
            .file_name()
            .expect("Embedded asset file has no name");
        std::fs::write(destination.join(name), file.contents())
            .expect("Failed to extract embedded asset");
    }

    for child in dir.dirs() {
        let name = child
            .path()
            .file_name()
            .expect("Embedded asset directory has no name");
        extract_dir(child, &destination.join(name));
    }
}
