use rusqlite::Connection;
use serde_json::{json, Value};
use wilayah::builder::{ParseOutputDetail, Pipeline};
fn main() {
let args: Vec<String> = std::env::args().collect();
let mut pipeline = Pipeline::new();
let mut save_legacy_snapshot = false;
let mut skip_big = false;
if std::env::var("WILAYAH_REFRESH_BIG").as_deref() == Ok("1") {
pipeline = pipeline.force_refresh_big(true);
}
let mut cache_dir = std::path::PathBuf::from("data/cache");
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--output" | "-o" => {
if i + 1 < args.len() {
pipeline = pipeline.output(std::path::Path::new(&args[i + 1]));
i += 2;
} else {
eprintln!("error: --output requires a path");
std::process::exit(1);
}
}
"--cache-dir" => {
if i + 1 < args.len() {
cache_dir = std::path::PathBuf::from(&args[i + 1]);
pipeline = pipeline.cache_dir(&cache_dir);
i += 2;
} else {
eprintln!("error: --cache-dir requires a path");
std::process::exit(1);
}
}
"--pdf-url" => {
if i + 1 < args.len() {
pipeline = pipeline.pdf_url(&args[i + 1]);
i += 2;
} else {
eprintln!("error: --pdf-url requires a URL");
std::process::exit(1);
}
}
"--big-api-url" => {
if i + 1 < args.len() {
pipeline = pipeline.big_api_url(&args[i + 1]);
i += 2;
} else {
eprintln!("error: --big-api-url requires a URL");
std::process::exit(1);
}
}
"--force-refresh-big" => {
pipeline = pipeline.force_refresh_big(true);
i += 1;
}
"--skip-big" => {
skip_big = true;
i += 1;
}
"--save-legacy-snapshot" => {
save_legacy_snapshot = true;
i += 1;
}
"--include-polygons" => {
pipeline = pipeline.include_polygons(true);
i += 1;
}
"--save-parsed-villages" => {
let detail = if i + 1 < args.len() && !args[i + 1].starts_with('-') {
let level = &args[i + 1];
i += 2;
match level.as_str() {
"minimal" => ParseOutputDetail::Minimal,
"raw" => ParseOutputDetail::WithRawName,
"full" => ParseOutputDetail::Full,
_ => {
eprintln!(
"error: unknown detail level '{level}' (use minimal, raw, or full)"
);
std::process::exit(1);
}
}
} else {
i += 1;
ParseOutputDetail::Minimal
};
pipeline = pipeline.save_parsed_villages(detail);
}
_ => {
eprintln!("warning: unknown argument: {}", args[i]);
i += 1;
}
}
}
if skip_big {
pipeline = pipeline
.force_refresh_big(false)
.big_api_url("http://127.0.0.1:9999/nonexistent");
}
match pipeline.run() {
Ok(output) => {
println!("Pipeline completed successfully.");
println!("Database: {}", output.db_path.display());
if let Some(poly) = &output.poly_db_path {
println!("Polygon DB: {}", poly.display());
}
if let Some(parsed) = &output.parsed_villages_path {
println!("Parsed villages: {}", parsed.display());
}
if let Some(dist) = &output.parsed_districts_path {
println!("Parsed districts: {}", dist.display());
}
if let Some(prov) = &output.parsed_provinces_path {
println!("Parsed provinces: {}", prov.display());
}
if let Some(city) = &output.parsed_cities_path {
println!("Parsed cities: {}", city.display());
}
if let Some(sum) = &output.parsed_island_summaries_path {
println!("Parsed island summaries: {}", sum.display());
}
if let Some(isl) = &output.parsed_islands_path {
println!("Parsed islands: {}", isl.display());
}
println!("Villages: {}", output.village_count);
println!("SHA-256: {}", output.sha256);
if save_legacy_snapshot {
if let Err(e) = save_legacy_snapshot_to(&output.db_path, &cache_dir) {
eprintln!("Failed to save legacy snapshot: {}", e);
std::process::exit(1);
}
}
std::process::exit(0);
}
Err(e) => {
eprintln!("Pipeline failed: {}", e);
std::process::exit(1);
}
}
}
fn save_legacy_snapshot_to(
db_path: &std::path::Path,
cache_dir: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
let conn = Connection::open(db_path)?;
let mut stmt = conn.prepare(
"SELECT kode, nama, kecamatan, kota, provinsi, lat, lon FROM locations ORDER BY kode",
)?;
let mut snapshot = Vec::new();
let mut rows = stmt.query([])?;
while let Some(row) = rows.next()? {
let village: Value = json!({
"code": row.get::<_, String>(0)?,
"name": row.get::<_, String>(1)?,
"district": row.get::<_, String>(2)?,
"city": row.get::<_, String>(3)?,
"province": row.get::<_, String>(4)?,
"lat": row.get::<_, f64>(5)?,
"lon": row.get::<_, f64>(6)?,
});
snapshot.push(village);
}
let snapshot_path = cache_dir.join("legacy_snapshot.json");
std::fs::create_dir_all(snapshot_path.parent().unwrap())?;
let file = std::fs::File::create(&snapshot_path)?;
serde_json::to_writer_pretty(file, &snapshot)?;
eprintln!("Saved legacy snapshot to {}", snapshot_path.display());
Ok(())
}