use clap::ArgMatches;
use crate::instance::InstanceManager;
use crate::instance::import::{ImportInput, parse_import_input};
use crate::net::modrinth;
type CliResult = Result<(), Box<dyn std::error::Error>>;
pub async fn handle_import(matches: &ArgMatches) -> CliResult {
let input = matches.get_one::<String>("source").unwrap();
let override_name = matches.get_one::<String>("name");
let override_version = matches.get_one::<String>("version");
let instances_dir = crate::config::SETTINGS.paths.resolve_instances_dir();
let meta_dir = crate::config::SETTINGS.paths.resolve_meta_dir();
let manager = InstanceManager::new(instances_dir, meta_dir);
let client = crate::net::HttpClient::new();
let parsed = parse_import_input(input);
let archive_path = match parsed {
ImportInput::LocalFile(ref path) => {
let resolved = crate::config::settings::resolve_path(path);
if !resolved.exists() {
return Err(format!("File not found: {}", resolved.display()).into());
}
resolved
}
ImportInput::ProjectSlug(ref slug) => {
println!("Fetching project '{slug}'...");
let project = modrinth::fetch_project(&client, slug)
.await
.map_err(|e| format!("Failed to fetch project: {e}"))?;
println!("Found: {}", project.title);
let versions = modrinth::fetch_versions(&client, slug)
.await
.map_err(|e| format!("Failed to fetch versions: {e}"))?;
if versions.is_empty() {
return Err("No versions found for this modpack".into());
}
let version = if let Some(version_name) = override_version {
versions
.iter()
.find(|v| v.version_number == *version_name || v.name == *version_name)
.ok_or_else(|| format!("Version '{version_name}' not found"))?
} else {
&versions[0]
};
println!(
"Using version {} ({})",
version.version_number,
version.game_versions.first().unwrap_or(&"?".to_string())
);
let tmp_dir = manager.meta_dir.join("tmp");
std::fs::create_dir_all(&tmp_dir)?;
modrinth::download_mrpack(&client, version, &tmp_dir)
.await
.map_err(|e| format!("Failed to download .mrpack: {e}"))?
}
ImportInput::VersionId {
slug: _,
ref version_id,
} => {
println!("Fetching version '{version_id}'...");
let version = modrinth::fetch_version(&client, version_id)
.await
.map_err(|e| format!("Failed to fetch version: {e}"))?;
println!(
"Found: {} ({})",
version.version_number,
version.game_versions.first().unwrap_or(&"?".to_string())
);
let tmp_dir = manager.meta_dir.join("tmp");
std::fs::create_dir_all(&tmp_dir)?;
modrinth::download_mrpack(&client, &version, &tmp_dir)
.await
.map_err(|e| format!("Failed to download .mrpack: {e}"))?
}
};
let mut summary = crate::instance::import::build_summary(&archive_path)
.map_err(|e| format!("Invalid modpack: {e}"))?;
if let Some(name) = override_name {
summary.name = name.clone();
}
println!(
"Importing '{}' - {} {} ({} mods, {} overrides)",
summary.name,
summary.game_version,
summary.loader,
summary.mod_count,
summary.override_count
);
let config = crate::instance::import::execute_import(&summary, &manager)
.await
.map_err(|e| format!("Import failed: {e}"))?;
println!("Instance '{}' created successfully.", config.name);
Ok(())
}