//! L9 tests for the local remote-host strategy and the host selector.

use std::path::PathBuf;
use std::sync::Arc;

use domain::ports::{RemoteError, RemoteHost, RemotePath};
use domain::remote::{RemoteKind, RemoteRef, SshAuth};
use infrastructure::{remote_host, LocalHost};
use uuid::Uuid;

struct TempDir(PathBuf);
impl TempDir {
    fn new() -> Self {
        let p = std::env::temp_dir().join(format!("idea-l9-host-{}", Uuid::new_v4()));
        std::fs::create_dir_all(&p).unwrap();
        Self(p)
    }
    fn path(&self) -> String {
        self.0.to_string_lossy().into_owned()
    }
}
impl Drop for TempDir {
    fn drop(&mut self) {
        let _ = std::fs::remove_dir_all(&self.0);
    }
}

#[tokio::test]
async fn local_host_connects_and_exposes_local_fs() {
    let tmp = TempDir::new();
    let host = LocalHost::new();
    assert_eq!(host.kind(), RemoteKind::Local);
    host.connect().await.expect("local connect is a no-op");

    let fs = host.file_system();
    assert!(fs.exists(&RemotePath::new(tmp.path())).await.unwrap());
    assert!(!fs
        .exists(&RemotePath::new(format!("{}/nope", tmp.path())))
        .await
        .unwrap());
}

#[tokio::test]
async fn selector_builds_local_host() {
    let host = remote_host(&RemoteRef::local()).expect("local host builds");
    assert_eq!(host.kind(), RemoteKind::Local);
}

#[test]
fn selector_rejects_ssh_and_wsl_for_now() {
    let ssh = RemoteRef::ssh("h", 22, "u", SshAuth::Agent, "/srv").unwrap();
    assert!(matches!(remote_host(&ssh), Err(RemoteError::Connection(_))));
    let wsl = RemoteRef::wsl("Ubuntu").unwrap();
    assert!(matches!(remote_host(&wsl), Err(RemoteError::Connection(_))));
}

/// Local host PTY/spawner handles are cloneable port objects (Arc-backed).
#[test]
fn local_host_hands_out_ports() {
    let host: Arc<dyn RemoteHost> = Arc::new(LocalHost::new());
    let _fs = host.file_system();
    let _sp = host.process_spawner();
    let _pty = host.pty();
}
