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("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(format!("submodule.{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(format!("submodule.{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(format!("submodule.{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(format!("submodule.{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(format!("submodule.{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(format!("submodule.{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(format!("submodule.{name}.shallow")).transpose()
    }
}
