//! Helpers for initializing the remote and local disk location of an index

use crate::{Error, Path, PathBuf};
use std::borrow::Cow;

/// A remote index url
#[derive(Default, Debug)]
pub enum IndexUrl<'iu> {
    /// The canonical crates.io HTTP sparse index.
    ///
    /// See [`crate::CRATES_IO_HTTP_INDEX`]
    #[default]
    CratesIoSparse,
    /// The canonical crates.io git index.
    ///
    /// See [`crate::CRATES_IO_INDEX`]
    CratesIoGit,
    /// A non-crates.io index.
    ///
    /// This variant uses the url to determine the index kind (sparse or git) by
    /// inspecting the url's scheme. This is because sparse indices are required
    /// to have the `sparse+` scheme modifier
    NonCratesIo(Cow<'iu, str>),
    /// A [local registry](crate::index::LocalRegistry)
    Local(Cow<'iu, Path>),
}

impl<'iu> IndexUrl<'iu> {
    /// Gets the url as a string
    pub fn as_str(&'iu self) -> &'iu str {
        match self {
            Self::CratesIoSparse => crate::CRATES_IO_HTTP_INDEX,
            Self::CratesIoGit => crate::CRATES_IO_INDEX,
            Self::NonCratesIo(url) => url,
            Self::Local(pb) => pb.as_str(),
        }
    }

    /// Returns true if the url points to a sparse registry
    pub fn is_sparse(&self) -> bool {
        match self {
            Self::CratesIoSparse => true,
            Self::CratesIoGit | Self::Local(..) => false,
            Self::NonCratesIo(url) => url.starts_with("sparse+http"),
        }
    }

    /// Gets the [`IndexUrl`] for crates.io, depending on the local environment.
    ///
    /// 1. Determines if the crates.io registry has been [replaced](https://doc.rust-lang.org/cargo/reference/source-replacement.html)
    /// 2. Determines if the protocol was explicitly [configured](https://doc.rust-lang.org/cargo/reference/config.html#registriescrates-ioprotocol) by the user
    /// 3. Otherwise, detects the version of cargo (see [`crate::utils::cargo_version`]), and uses that to determine the appropriate default
    pub fn crates_io(
        config_root: Option<PathBuf>,
        cargo_home: Option<&Path>,
        cargo_version: Option<&str>,
    ) -> Result<Self, Error> {
        // If the crates.io registry has been replaced it doesn't matter what
        // the protocol for it has been changed to
        if let Some(replacement) = get_crates_io_replacement(config_root.clone(), cargo_home)? {
            return Ok(replacement);
        }

        let sparse_index = match std::env::var("CARGO_REGISTRIES_CRATES_IO_PROTOCOL")
            .ok()
            .as_deref()
        {
            Some("sparse") => true,
            Some("git") => false,
            _ => {
                let sparse_index =
                    read_cargo_config(config_root, cargo_home, |config| {
                        match config
                            .pointer("/registries/crates-io/protocol")
                            .and_then(|p| p.as_str())?
                        {
                            "sparse" => Some(true),
                            "git" => Some(false),
                            _ => None,
                        }
                    })?;

                if let Some(si) = sparse_index {
                    si
                } else {
                    let vers = match cargo_version {
                        Some(v) => v.trim().parse()?,
                        None => crate::utils::cargo_version(None)?,
                    };

                    vers >= semver::Version::new(1, 70, 0)
                }
            }
        };

        Ok(if sparse_index {
            Self::CratesIoSparse
        } else {
            Self::CratesIoGit
        })
    }
}

impl<'iu> From<&'iu str> for IndexUrl<'iu> {
    #[inline]
    fn from(s: &'iu str) -> Self {
        Self::NonCratesIo(s.into())
    }
}

/// The local disk location to place an index
#[derive(Default)]
pub enum IndexPath {
    /// The default cargo home root path
    #[default]
    CargoHome,
    /// User-specified root path
    UserSpecified(PathBuf),
    /// An exact path on disk where an index is located.
    ///
    /// Unlike the other two variants, this variant won't take the index's url
    /// into account to calculate the unique url hash as part of the full path
    Exact(PathBuf),
}

impl From<Option<PathBuf>> for IndexPath {
    /// Converts an optional path to a rooted path.
    ///
    /// This never constructs a [`Self::Exact`], that can only be done explicitly
    fn from(pb: Option<PathBuf>) -> Self {
        if let Some(pb) = pb {
            Self::UserSpecified(pb)
        } else {
            Self::CargoHome
        }
    }
}

/// Helper for constructing an index location, consisting of the remote url for
/// the index and the local location on disk
#[derive(Default)]
pub struct IndexLocation<'il> {
    /// The remote url of the registry index
    pub url: IndexUrl<'il>,
    /// The local disk path of the index
    pub root: IndexPath,
}

impl<'il> IndexLocation<'il> {
    /// Constructs an index with the specified url located in the default cargo
    /// home
    pub fn new(url: IndexUrl<'il>) -> Self {
        Self {
            url,
            root: IndexPath::CargoHome,
        }
    }

    /// Changes the root location of the index on the local disk.
    ///
    /// If not called, or set to [`None`], the default cargo home disk location
    /// is used as the root
    pub fn with_root(mut self, root: Option<PathBuf>) -> Self {
        self.root = root.into();
        self
    }

    /// Obtains the full local disk path and URL of this index location
    pub fn into_parts(self) -> Result<(PathBuf, String), Error> {
        let url = self.url.as_str();

        let root = match self.root {
            IndexPath::CargoHome => crate::utils::cargo_home()?,
            IndexPath::UserSpecified(root) => root,
            IndexPath::Exact(path) => return Ok((path, url.to_owned())),
        };

        let (path, mut url) = crate::utils::get_index_details(url, Some(root))?;

        if !url.ends_with('/') {
            url.push('/');
        }

        Ok((path, url))
    }
}

/// Calls the specified function for each cargo config located according to
/// cargo's standard hierarchical structure
///
/// Note that this only supports the use of `.cargo/config.toml`, which is not
/// supported below cargo 1.39.0
///
/// See <https://doc.rust-lang.org/cargo/reference/config.html#hierarchical-structure>
pub(crate) fn read_cargo_config<T>(
    root: Option<PathBuf>,
    cargo_home: Option<&Path>,
    callback: impl Fn(&toml_span::value::Value<'_>) -> Option<T>,
) -> Result<Option<T>, Error> {
    if let Some(mut path) = root.or_else(|| {
        std::env::current_dir()
            .ok()
            .and_then(|pb| PathBuf::from_path_buf(pb).ok())
    }) {
        loop {
            path.push(".cargo/config.toml");
            if path.exists() {
                let contents = match std::fs::read_to_string(&path) {
                    Ok(c) => c,
                    Err(err) => return Err(Error::IoPath(err, path)),
                };

                let toml = toml_span::parse(&contents).map_err(Box::new)?;
                if let Some(value) = callback(&toml) {
                    return Ok(Some(value));
                }
            }
            path.pop();
            path.pop();

            // Walk up to the next potential config root
            if !path.pop() {
                break;
            }
        }
    }

    if let Some(home) = cargo_home
        .map(Cow::Borrowed)
        .or_else(|| crate::utils::cargo_home().ok().map(Cow::Owned))
    {
        let path = home.join("config.toml");
        if path.exists() {
            let fc = std::fs::read_to_string(&path)?;
            let toml = toml_span::parse(&fc).map_err(Box::new)?;
            if let Some(value) = callback(&toml) {
                return Ok(Some(value));
            }
        }
    }

    Ok(None)
}

/// Gets the url of a replacement registry for crates.io if one has been configured
///
/// See <https://doc.rust-lang.org/cargo/reference/source-replacement.html>
#[inline]
pub(crate) fn get_crates_io_replacement<'iu>(
    root: Option<PathBuf>,
    cargo_home: Option<&Path>,
) -> Result<Option<IndexUrl<'iu>>, Error> {
    read_cargo_config(root, cargo_home, |config| {
        let repw = config.pointer("/source/crates-io/replace-with")?.as_str()?;
        let sources = config.pointer("/source")?.as_table()?;
        let replace_src = sources.get(&repw.into())?.as_table()?;

        if let Some(rr) = replace_src.get(&"registry".into()) {
            rr.as_str()
                .map(|r| IndexUrl::NonCratesIo(r.to_owned().into()))
        } else if let Some(rlr) = replace_src.get(&"local-registry".into()) {
            rlr.as_str()
                .map(|l| IndexUrl::Local(PathBuf::from(l).into()))
        } else {
            None
        }
    })
}

#[cfg(test)]
mod test {
    // Current stable is 1.70.0
    #[test]
    fn opens_sparse() {
        assert!(std::env::var_os("CARGO_REGISTRIES_CRATES_IO_PROTOCOL").is_none());
        assert!(matches!(
            crate::index::ComboIndexCache::new(super::IndexLocation::new(
                super::IndexUrl::crates_io(None, None, None).unwrap()
            ))
            .unwrap(),
            crate::index::ComboIndexCache::Sparse(_)
        ));
    }

    /// Verifies we can parse .cargo/config.toml files to either use the crates-io
    /// protocol set, or source replacements
    #[test]
    fn parses_from_file() {
        assert!(std::env::var_os("CARGO_REGISTRIES_CRATES_IO_PROTOCOL").is_none());

        let td = tempfile::tempdir().unwrap();
        let root = crate::PathBuf::from_path_buf(td.path().to_owned()).unwrap();
        let cfg_toml = td.path().join(".cargo/config.toml");

        std::fs::create_dir_all(cfg_toml.parent().unwrap()).unwrap();

        const GIT: &str = r#"[registries.crates-io]
protocol = "git"
"#;

        // First just set the protocol from the sparse default to git
        std::fs::write(&cfg_toml, GIT).unwrap();

        let iurl = super::IndexUrl::crates_io(Some(root.clone()), None, None).unwrap();
        assert_eq!(iurl.as_str(), crate::CRATES_IO_INDEX);
        assert!(!iurl.is_sparse());

        // Next set replacement registries
        for (i, (kind, url)) in [
            (
                "registry",
                "sparse+https://sparse-registry-parses-from-file.com",
            ),
            ("registry", "https://sparse-registry-parses-from-file.git"),
            ("local-registry", root.as_str()),
        ]
        .iter()
        .enumerate()
        {
            std::fs::write(&cfg_toml, format!("{GIT}\n[source.crates-io]\nreplace-with = 'replacement'\n[source.replacement]\n{kind} = '{url}'")).unwrap();

            let iurl = super::IndexUrl::crates_io(Some(root.clone()), None, None).unwrap();
            assert_eq!(i == 0, iurl.is_sparse());
            assert_eq!(iurl.as_str(), *url);
        }
    }
}
