use std::{borrow::Cow, collections::HashSet, path::Path};

use bstr::BStr;

use crate::{
    config,
    config::{Branch, FetchRecurse, Ignore, Update},
    File, IsActivePlatform,
};

/// High-Level Access
///
/// Note that all methods perform validation of the requested value and report issues right away.
/// If a bypass is needed, use [`config()`](File::config()) for direct access.
impl File {
    /// Return the underlying configuration file.
    ///
    /// Note that it might have been merged with values from another configuration file and may
    /// thus not be accurately reflecting that state of a `.gitmodules` file anymore.
    pub fn config(&self) -> &gix_config::File<'static> {
        &self.config
    }

    /// Return the path at which the `.gitmodules` file lives, if it is known.
    pub fn config_path(&self) -> Option<&Path> {
        self.config.sections().filter_map(|s| s.meta().path.as_deref()).next()
    }

    /// Return the unvalidated names of the submodules for which configuration is present.
    ///
    /// Note that these exact names have to be used for querying submodule values.
    pub fn names(&self) -> impl Iterator<Item = &BStr> {
        let mut seen = HashSet::<&BStr>::default();
        self.config
            .sections_by_name("submodule")
            .into_iter()
            .flatten()
            .filter_map(move |s| {
                s.header()
                    .subsection_name()
                    .filter(|_| s.meta().source == crate::init::META_MARKER)
                    .filter(|name| seen.insert(*name))
            })
    }

    /// Similar to [Self::is_active_platform()], but automatically applies it to each name to learn if a submodule is active or not.
    pub fn names_and_active_state<'a>(
        &'a self,
        config: &'a gix_config::File<'static>,
        defaults: gix_pathspec::Defaults,
        attributes: &'a mut (dyn FnMut(
            &BStr,
            gix_pathspec::attributes::glob::pattern::Case,
            bool,
            &mut gix_pathspec::attributes::search::Outcome,
        ) -> bool
                     + 'a),
    ) -> Result<
        impl Iterator<Item = (&BStr, Result<bool, gix_config::value::Error>)> + 'a,
        crate::is_active_platform::Error,
    > {
        let mut platform = self.is_active_platform(config, defaults)?;
        let iter = self
            .names()
            .map(move |name| (name, platform.is_active(config, name, attributes)));
        Ok(iter)
    }

    /// Return a platform which allows to check if a submodule name is active or inactive.
    /// Use `defaults` for parsing the pathspecs used to later match on names via `submodule.active` configuration retrieved from `config`.
    ///
    /// All `submodule.active` pathspecs are considered to be top-level specs and match the name of submodules, which are active
    /// on inclusive match.
    /// The full algorithm is described as [hierarchy of rules](https://git-scm.com/docs/gitsubmodules#_active_submodules).
    pub fn is_active_platform(
        &self,
        config: &gix_config::File<'_>,
        defaults: gix_pathspec::Defaults,
    ) -> Result<IsActivePlatform, crate::is_active_platform::Error> {
        let search = config
            .strings_by_key("submodule.active")
            .map(|patterns| -> Result<_, crate::is_active_platform::Error> {
                let patterns = patterns
                    .into_iter()
                    .map(|pattern| gix_pathspec::parse(&pattern, defaults))
                    .collect::<Result<Vec<_>, _>>()?;
                Ok(gix_pathspec::Search::from_specs(
                    patterns,
                    None,
                    std::path::Path::new(""),
                )?)
            })
            .transpose()?;
        Ok(IsActivePlatform { search })
    }

    /// Given the `relative_path` (as seen from the root of the worktree) of a submodule with possibly platform-specific
    /// component separators, find the submodule's name associated with this path, or `None` if none was found.
    ///
    /// Note that this does a linear search and compares `relative_path` in a normalized form to the same form of the path
    /// associated with the submodule.
    pub fn name_by_path(&self, relative_path: &BStr) -> Option<&BStr> {
        self.names()
            .filter_map(|n| self.path(n).ok().map(|p| (n, p)))
            .find_map(|(n, p)| (p == relative_path).then_some(n))
    }
}

/// Per-Submodule Access
impl File {
    /// Return the path relative to the root directory of the working tree at which the submodule is expected to be checked out.
    /// It's an error if the path doesn't exist as it's the only way to associate a path in the index with additional submodule
    /// information, like the URL to fetch from.
    ///
    /// ### Deviation
    ///
    /// Git currently allows absolute paths to be used when adding submodules, but fails later as it can't find the submodule by
    /// relative path anymore. Let's play it safe here.
    pub fn path(&self, name: &BStr) -> Result<Cow<'_, BStr>, config::path::Error> {
        let path_bstr =
            self.config
                .string("submodule", Some(name), "path")
                .ok_or_else(|| config::path::Error::Missing {
                    submodule: name.to_owned(),
                })?;
        if path_bstr.is_empty() {
            return Err(config::path::Error::Missing {
                submodule: name.to_owned(),
            });
        }
        let path = gix_path::from_bstr(path_bstr.as_ref());
        if path.is_absolute() {
            return Err(config::path::Error::Absolute {
                submodule: name.to_owned(),
                actual: path_bstr.into_owned(),
            });
        }
        if gix_path::normalize(path, "".as_ref()).is_none() {
            return Err(config::path::Error::OutsideOfWorktree {
                submodule: name.to_owned(),
                actual: path_bstr.into_owned(),
            });
        }
        Ok(path_bstr)
    }

    /// Retrieve the `url` field of the submodule named `name`. It's an error if it doesn't exist or is empty.
    pub fn url(&self, name: &BStr) -> Result<gix_url::Url, config::url::Error> {
        let url = self
            .config
            .string("submodule", Some(name), "url")
            .ok_or_else(|| config::url::Error::Missing {
                submodule: name.to_owned(),
            })?;

        if url.is_empty() {
            return Err(config::url::Error::Missing {
                submodule: name.to_owned(),
            });
        }
        gix_url::Url::from_bytes(url.as_ref()).map_err(|err| config::url::Error::Parse {
            submodule: name.to_owned(),
            source: err,
        })
    }

    /// Retrieve the `update` field of the submodule named `name`, if present.
    pub fn update(&self, name: &BStr) -> Result<Option<Update>, config::update::Error> {
        let value: Update = match self.config.string("submodule", Some(name), "update") {
            Some(v) => v.as_ref().try_into().map_err(|()| config::update::Error::Invalid {
                submodule: name.to_owned(),
                actual: v.into_owned(),
            })?,
            None => return Ok(None),
        };

        if let Update::Command(cmd) = &value {
            let ours = self.config.meta();
            let has_value_from_foreign_section = self
                .config
                .sections_by_name("submodule")
                .into_iter()
                .flatten()
                .any(|s| (s.header().subsection_name() == Some(name) && s.meta() as *const _ != ours as *const _));
            if !has_value_from_foreign_section {
                return Err(config::update::Error::CommandForbiddenInModulesConfiguration {
                    submodule: name.to_owned(),
                    actual: cmd.to_owned(),
                });
            }
        }
        Ok(Some(value))
    }

    /// Retrieve the `branch` field of the submodule named `name`, or `None` if unset.
    ///
    /// Note that `Default` is implemented for [`Branch`].
    pub fn branch(&self, name: &BStr) -> Result<Option<Branch>, config::branch::Error> {
        let branch = match self.config.string("submodule", Some(name), "branch") {
            Some(v) => v,
            None => return Ok(None),
        };

        Branch::try_from(branch.as_ref())
            .map(Some)
            .map_err(|err| config::branch::Error {
                submodule: name.to_owned(),
                actual: branch.into_owned(),
                source: err,
            })
    }

    /// Retrieve the `fetchRecurseSubmodules` field of the submodule named `name`, or `None` if unset.
    ///
    /// Note that if it's unset, it should be retrieved from `fetch.recurseSubmodules` in the configuration.
    pub fn fetch_recurse(&self, name: &BStr) -> Result<Option<FetchRecurse>, config::Error> {
        self.config
            .boolean("submodule", Some(name), "fetchRecurseSubmodules")
            .map(FetchRecurse::new)
            .transpose()
            .map_err(|value| config::Error {
                field: "fetchRecurseSubmodules",
                submodule: name.to_owned(),
                actual: value,
            })
    }

    /// Retrieve the `ignore` field of the submodule named `name`, or `None` if unset.
    pub fn ignore(&self, name: &BStr) -> Result<Option<Ignore>, config::Error> {
        self.config
            .string("submodule", Some(name), "ignore")
            .map(|value| {
                Ignore::try_from(value.as_ref()).map_err(|()| config::Error {
                    field: "ignore",
                    submodule: name.to_owned(),
                    actual: value.into_owned(),
                })
            })
            .transpose()
    }

    /// Retrieve the `shallow` field of the submodule named `name`, or `None` if unset.
    ///
    /// If `true`, the submodule will be checked out with `depth = 1`. If unset, `false` is assumed.
    pub fn shallow(&self, name: &BStr) -> Result<Option<bool>, gix_config::value::Error> {
        self.config.boolean("submodule", Some(name), "shallow").transpose()
    }
}
