use colored::*;
use crate::adb::{find_adb, list_devices, select_device};
use crate::config::PalpConfig;
use crate::error::PalpError;
use crate::probe::probe_device;
pub fn run_doctor(target_device: Option<&str>) -> Result<(), PalpError> {
println!("{}", "🩺 palp Doctor - Diagnostic Health Check".bold().cyan());
println!("{}", "=========================================".cyan());
print!("Checking Android Debug Bridge (ADB)... ");
let adb_path = match find_adb() {
Ok(path) => {
println!("{} ({})", "✓ FOUND".green().bold(), path.display());
path
}
Err(_) => {
println!("{}", "✗ NOT FOUND".red().bold());
println!("\n{}", "Advice:".yellow().bold());
println!("Please install Android SDK platform-tools or set ANDROID_HOME in your environment variables.");
return Ok(());
}
};
print!("Scanning for connected devices... ");
let devices = match list_devices(&adb_path) {
Ok(devs) => devs,
Err(e) => {
println!("{}", "✗ ERROR".red().bold());
println!("Could not query devices: {}", e);
return Ok(());
}
};
if devices.is_empty() {
println!("{}", "✗ NO DEVICES FOUND".red().bold());
println!("\n{}", "Advice:".yellow().bold());
println!("1. Connect your Android phone via USB or launch an Android emulator.");
println!("2. On your physical phone, enable Developer Options and turn on 'USB Debugging'.");
return Ok(());
}
println!("{} (found {})", "✓ CONNECTED".green().bold(), devices.len());
for d in &devices {
let auth_badge = if d.state == "device" {
"Authorized".green()
} else {
"Unauthorized / Offline".red().bold()
};
let kind = if d.is_emulator { "Emulator" } else { "Physical Phone" };
println!(" • {} [{}] - {} ({})", d.serial.cyan(), kind, d.model, auth_badge);
}
let active_device = match select_device(target_device) {
Ok(d) => d,
Err(e) => {
println!("\n{}", format!("Device selection: {}", e).yellow());
return Ok(());
}
};
println!("\n{} Active Device: {} ({})", "📱".green(), active_device.serial.bold(), active_device.model);
print!("Checking screen display state... ");
let power_state = active_device.shell("dumpsys power | grep -i 'mHoldingDisplaySuspendBlocker\\|mWakefulness'").unwrap_or_default();
let is_awake = power_state.contains("mHoldingDisplaySuspendBlocker=true") || power_state.to_lowercase().contains("awake");
if is_awake {
println!("{}", "✓ AWAKE & READY".green().bold());
} else {
println!("{}", "! SCREEN OFF OR SLEEPING".yellow().bold());
println!(" Advice: Press power button on your phone or run `palp press power` to wake it.");
}
print!("Probing screen resolution & insets... ");
match probe_device(&active_device) {
Ok(metrics) => {
println!("{}", "✓ SUCCESS".green().bold());
println!(" • Resolution: {}x{} @ {} DPI ({}x scale)",
metrics.width, metrics.height, metrics.density_dpi, metrics.scale_factor
);
println!(" • Safe Viewport: {}x{} px", metrics.content_width(), metrics.content_height());
println!(" • Status Bar Inset: {} px (top cut)", metrics.status_bar_height);
println!(" • Gesture Bar Inset: {} px (bottom cut)", metrics.navigation_bar_height);
}
Err(e) => {
println!("{} ({})", "! WARNING".yellow().bold(), e);
}
}
let config = PalpConfig::load();
println!("\nProject Configuration (.palprc.json):");
if config.targets.is_empty() {
println!(" • No custom target shortcuts defined yet. You can tap by text: `palp tap-text \"Button\"`");
} else {
println!(" • {} target shortcut(s) registered:", config.targets.len());
for (name, coords) in &config.targets {
println!(" - {}: [{}, {}]", name.cyan(), coords.0, coords.1);
}
}
println!("\n{}", "🎉 All systems operational! palp is ready for agentic & developer navigation.".green().bold());
Ok(())
}