//! VS Code local config reader.
//!
//! VS Code (1.99+) stores user-level MCP servers in `mcp.json` under its User
//! profile directory, which differs by platform:
//!
//! - macOS:   `~/Library/Application Support/Code/User/mcp.json`
//! - Linux:   `$XDG_CONFIG_HOME/Code/User/mcp.json` (or `~/.config/...`)
//! - Windows: `%APPDATA%\Code\User\mcp.json`
//!
//! VS Code keys its map `servers` rather than `mcpServers`; the shared parser
//! accepts either, so this module only resolves the path. Workspace-local
//! `.vscode/mcp.json` files are out of scope (the runner picks those up via the
//! explicit `--config` flag). If VS Code shifts its path, this module is the
//! single place to update. Read-only.

use std::path::PathBuf;

use super::{parse_mcp_servers_file, ClientSource, DiscoveredServer, DiscoveryError};

/// Discover servers declared in VS Code's user `mcp.json`.
///
/// Empty vec when the file does not exist (VS Code is not installed, or the
/// user keeps their MCP config workspace-local).
pub fn discover_servers() -> Result<Vec<DiscoveredServer>, DiscoveryError> {
    let Some(path) = config_path() else {
        return Ok(Vec::new());
    };
    parse_mcp_servers_file(&path, ClientSource::VsCode)
}

/// Resolve the platform-specific VS Code user `mcp.json` path, or `None` when
/// the home / config directory cannot be resolved.
pub(super) fn config_path() -> Option<PathBuf> {
    let user_dir = if cfg!(target_os = "macos") {
        let home = std::env::var_os("HOME")?;
        PathBuf::from(home)
            .join("Library")
            .join("Application Support")
            .join("Code")
            .join("User")
    } else if cfg!(target_os = "windows") {
        let appdata = std::env::var_os("APPDATA")?;
        PathBuf::from(appdata).join("Code").join("User")
    } else {
        let config = std::env::var_os("XDG_CONFIG_HOME")
            .map(PathBuf::from)
            .or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".config")))?;
        config.join("Code").join("User")
    };
    Some(user_dir.join("mcp.json"))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn config_path_lands_in_the_user_profile_mcp_json() {
        // On unix HOME is set in CI; on Windows APPDATA is. When neither the
        // home nor config dir resolves, the resolver returns None by design.
        let Some(path) = config_path() else {
            return;
        };
        assert!(path.ends_with("mcp.json"), "{path:?}");
        assert!(path.to_string_lossy().contains("Code"), "{path:?}");
    }

    #[test]
    fn discover_is_empty_when_the_file_is_absent() {
        assert!(discover_servers().is_ok());
    }
}
