//! Integration tests for [`FsSystemPermissionStore`] against a real temp project.

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

use domain::ids::{AgentId, ProjectId};
use domain::ports::{FileSystem, SystemPermissionStore};
use domain::project::{Project, ProjectPath};
use domain::remote::RemoteRef;
use domain::{
    AgentSystemPermissionOverride, NetworkPolicy, ProjectSystemPermissions, SystemPermissionSet,
    SYSTEM_PERMISSIONS_VERSION,
};
use infrastructure::{FsSystemPermissionStore, LocalFileSystem};
use uuid::Uuid;

struct TempDir(PathBuf);

impl TempDir {
    fn new() -> Self {
        let p = std::env::temp_dir().join(format!("idea-system-permissions-{}", Uuid::new_v4()));
        std::fs::create_dir_all(&p).unwrap();
        Self(p)
    }

    fn project_root(&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);
    }
}

fn store() -> FsSystemPermissionStore {
    let fs: Arc<dyn FileSystem> = Arc::new(LocalFileSystem::new());
    FsSystemPermissionStore::new(fs)
}

fn project(tmp: &TempDir) -> Project {
    Project::new(
        ProjectId::new_random(),
        "system-permissions",
        ProjectPath::new(tmp.project_root()).unwrap(),
        RemoteRef::local(),
        1_700_000_000_000,
    )
    .unwrap()
}

#[tokio::test]
async fn missing_system_permissions_file_returns_default_document() {
    let tmp = TempDir::new();
    let project = project(&tmp);

    let loaded = store().load_system_permissions(&project).await.unwrap();

    assert_eq!(loaded, ProjectSystemPermissions::default());
    assert_eq!(loaded.version, SYSTEM_PERMISSIONS_VERSION);
}

#[tokio::test]
async fn save_then_load_roundtrips_project_defaults_and_agent_override() {
    let tmp = TempDir::new();
    let project = project(&tmp);
    let agent = AgentId::new_random();
    let doc = ProjectSystemPermissions::new(
        Some(SystemPermissionSet::new(Some(NetworkPolicy::Ask))),
        vec![AgentSystemPermissionOverride::new(
            agent,
            SystemPermissionSet::new(Some(NetworkPolicy::Deny)),
        )],
    );

    let store = store();
    store.save_system_permissions(&project, &doc).await.unwrap();

    let loaded = store.load_system_permissions(&project).await.unwrap();
    assert_eq!(loaded, doc);
    assert_eq!(loaded.wanted_network_for(agent), Some(NetworkPolicy::Deny));

    let path = tmp.0.join(".ideai").join("system-permissions.json");
    assert!(
        path.exists(),
        "store writes under .ideai/system-permissions.json"
    );
}
