use bstr::{BStr, BString, ByteSlice};
use gix_glob::pattern::Case;

use crate::search::MatchKind;
use crate::search::MatchKind::*;
use crate::{
    search::{Match, Spec},
    MagicSignature, Pattern, Search, SearchMode,
};

impl Search {
    /// Return the first [`Match`] of `relative_path`, or `None`.
    /// `is_dir` is `true` if `relative_path` is a directory, or assumed `false` if `None`.
    /// `attributes` is called as `attributes(relative_path, case, is_dir, outcome) -> has_match` to obtain for attributes for `relative_path`, if
    /// the underlying pathspec defined an attribute filter, to be stored in `outcome`, returning true if there was a match.
    /// All attributes of the pathspec have to be present in the defined value for the pathspec to match.
    ///
    /// Note that `relative_path` is expected to be starting at the same root as is assumed for this pattern, see [`Pattern::normalize()`].
    /// Further, empty searches match everything, as if `:` was provided.
    ///
    /// ### Deviation
    ///
    /// The case-sensivity of the attribute match is controlled by the sensitivity of the pathspec, instead of being based on the
    /// case folding settings of the repository. That way we assure that the matching is consistent.
    /// Higher-level crates should control this default case folding of pathspecs when instantiating them, which is when they can
    /// set it to match the repository setting for more natural behaviour when, for instance, adding files to a repository:
    /// as it stands, on a case-insensitive file system, `touch File && git add file` will not add the file, but also not error.
    pub fn pattern_matching_relative_path(
        &mut self,
        relative_path: &BStr,
        is_dir: Option<bool>,
        attributes: &mut dyn FnMut(&BStr, Case, bool, &mut gix_attributes::search::Outcome) -> bool,
    ) -> Option<Match<'_>> {
        let basename_not_important = None;
        if relative_path
            .get(..self.common_prefix_len)
            .map_or(true, |rela_path_prefix| rela_path_prefix != self.common_prefix())
        {
            return None;
        }

        let is_dir = is_dir.unwrap_or(false);
        let patterns_len = self.patterns.len();
        let res = self.patterns.iter_mut().find_map(|mapping| {
            let ignore_case = mapping.value.pattern.signature.contains(MagicSignature::ICASE);
            let prefix = mapping.value.pattern.prefix_directory();
            if ignore_case && !prefix.is_empty() {
                let pattern_requirement_is_met = relative_path.get(prefix.len()).map_or_else(|| is_dir, |b| *b == b'/');
                if !pattern_requirement_is_met
                    || relative_path.get(..prefix.len()).map(ByteSlice::as_bstr) != Some(prefix)
                {
                    return None;
                }
            }

            let case = if ignore_case { Case::Fold } else { Case::Sensitive };
            let mut is_match = mapping.value.pattern.always_matches();
            let mut how = Always;
            if !is_match {
                is_match = if mapping.pattern.first_wildcard_pos.is_none() {
                    match_verbatim(mapping, relative_path, is_dir, case, &mut how)
                } else {
                    let wildmatch_mode = match mapping.value.pattern.search_mode {
                        SearchMode::ShellGlob => Some(gix_glob::wildmatch::Mode::empty()),
                        SearchMode::Literal => None,
                        SearchMode::PathAwareGlob => Some(gix_glob::wildmatch::Mode::NO_MATCH_SLASH_LITERAL),
                    };
                    match wildmatch_mode {
                        Some(wildmatch_mode) => {
                            let is_match = mapping.pattern.matches_repo_relative_path(
                                relative_path,
                                basename_not_important,
                                Some(is_dir),
                                case,
                                wildmatch_mode,
                            );
                            if !is_match {
                                match_verbatim(mapping, relative_path, is_dir, case, &mut how)
                            } else {
                                how = mapping.pattern.first_wildcard_pos.map_or(Verbatim, |_| WildcardMatch);
                                true
                            }
                        }
                        None => match_verbatim(mapping, relative_path, is_dir, case, &mut how),
                    }
                }
            }

            if let Some(attrs) = mapping.value.attrs_match.as_mut() {
                if !attributes(relative_path, Case::Sensitive, is_dir, attrs) {
                    // we have attrs, but it didn't match any
                    return None;
                }
                for (actual, expected) in attrs.iter_selected().zip(mapping.value.pattern.attributes.iter()) {
                    if actual.assignment != expected.as_ref() {
                        return None;
                    }
                }
            }

            is_match.then_some(Match {
                pattern: &mapping.value.pattern,
                sequence_number: mapping.sequence_number,
                kind: how,
            })
        });

        if res.is_none() && self.all_patterns_are_excluded {
            static MATCH_ALL_STAND_IN: Pattern = Pattern {
                path: BString::new(Vec::new()),
                signature: MagicSignature::empty(),
                search_mode: SearchMode::ShellGlob,
                attributes: Vec::new(),
                prefix_len: 0,
                nil: true,
            };
            Some(Match {
                pattern: &MATCH_ALL_STAND_IN,
                sequence_number: patterns_len,
                kind: Always,
            })
        } else {
            res
        }
    }

    /// As opposed to [`Self::pattern_matching_relative_path()`], this method will return `true` for a possibly partial `relative_path`
    /// if this pathspec *could* match by looking at the shortest shared prefix only.
    ///
    /// This is useful if `relative_path` is a directory leading up to the item that is going to be matched in full later.
    /// Note that it should not end with `/` to indicate it's a directory, rather, use `is_dir` to indicate this.
    /// `is_dir` is `true` if `relative_path` is a directory. If `None`, the fact that a pathspec might demand a directory match
    /// is ignored.
    /// Returns `false` if this pathspec has no chance of ever matching `relative_path`.
    pub fn can_match_relative_path(&self, relative_path: &BStr, is_dir: Option<bool>) -> bool {
        if self.patterns.is_empty() {
            return true;
        }
        let common_prefix_len = self.common_prefix_len.min(relative_path.len());
        if relative_path.get(..common_prefix_len).map_or(true, |rela_path_prefix| {
            rela_path_prefix != self.common_prefix()[..common_prefix_len]
        }) {
            return false;
        }
        for mapping in &self.patterns {
            let pattern = &mapping.value.pattern;
            if mapping.pattern.first_wildcard_pos == Some(0) && !pattern.is_excluded() {
                return true;
            }
            let max_usable_pattern_len = mapping.pattern.first_wildcard_pos.unwrap_or_else(|| pattern.path.len());
            let common_len = max_usable_pattern_len.min(relative_path.len());

            let ignore_case = pattern.signature.contains(MagicSignature::ICASE);
            let mut is_match = pattern.always_matches();
            if !is_match && common_len != 0 {
                let pattern_path = pattern.path[..common_len].as_bstr();
                let longest_possible_relative_path = &relative_path[..common_len];
                is_match = if ignore_case {
                    pattern_path.eq_ignore_ascii_case(longest_possible_relative_path)
                } else {
                    pattern_path == longest_possible_relative_path
                };

                if is_match {
                    is_match = if common_len < max_usable_pattern_len {
                        pattern.path.get(common_len) == Some(&b'/')
                    } else if relative_path.len() > max_usable_pattern_len
                        && mapping.pattern.first_wildcard_pos.is_none()
                    {
                        relative_path.get(common_len) == Some(&b'/')
                    } else {
                        is_match
                    };
                    if let Some(is_dir) = is_dir.filter(|_| pattern.signature.contains(MagicSignature::MUST_BE_DIR)) {
                        is_match = if is_dir {
                            matches!(pattern.path.get(common_len), None | Some(&b'/'))
                        } else {
                            relative_path.get(common_len) == Some(&b'/')
                        };
                    }
                }
            }
            if is_match && (!pattern.is_excluded() || pattern.always_matches()) {
                return !pattern.is_excluded();
            }
        }

        self.all_patterns_are_excluded
    }

    /// Returns `true` if `relative_path` matches the prefix of this pathspec.
    ///
    /// For example, the relative path `d` matches `d/`, `d*/`, `d/` and `d/*`, but not `d/d/*` or `dir`.
    /// When `leading` is `true`, then `d` matches `d/d` as well. Thus, `relative_path` must may be
    /// partially included in `pathspec`, otherwise it has to be fully included.
    pub fn directory_matches_prefix(&self, relative_path: &BStr, leading: bool) -> bool {
        if self.patterns.is_empty() {
            return true;
        }
        let common_prefix_len = self.common_prefix_len.min(relative_path.len());
        if relative_path.get(..common_prefix_len).map_or(true, |rela_path_prefix| {
            rela_path_prefix != self.common_prefix()[..common_prefix_len]
        }) {
            return false;
        }
        for mapping in &self.patterns {
            let pattern = &mapping.value.pattern;
            if mapping.pattern.first_wildcard_pos.is_some() && pattern.is_excluded() {
                return true;
            }
            let mut rightmost_idx = mapping.pattern.first_wildcard_pos.map_or_else(
                || pattern.path.len(),
                |idx| pattern.path[..idx].rfind_byte(b'/').unwrap_or(idx),
            );
            let ignore_case = pattern.signature.contains(MagicSignature::ICASE);
            let mut is_match = pattern.always_matches();
            if !is_match {
                let plen = relative_path.len();
                if leading && rightmost_idx > plen {
                    if let Some(idx) = pattern.path[..plen]
                        .rfind_byte(b'/')
                        .or_else(|| pattern.path[plen..].find_byte(b'/').map(|idx| idx + plen))
                    {
                        rightmost_idx = idx;
                    }
                }
                if let Some(relative_path) = relative_path.get(..rightmost_idx) {
                    let pattern_path = pattern.path[..rightmost_idx].as_bstr();
                    is_match = if ignore_case {
                        pattern_path.eq_ignore_ascii_case(relative_path)
                    } else {
                        pattern_path == relative_path
                    };
                }
            }
            if is_match && (!pattern.is_excluded() || pattern.always_matches()) {
                return !pattern.is_excluded();
            }
        }

        self.all_patterns_are_excluded
    }
}

fn match_verbatim(
    mapping: &gix_glob::search::pattern::Mapping<Spec>,
    relative_path: &BStr,
    is_dir: bool,
    case: Case,
    how: &mut MatchKind,
) -> bool {
    let pattern_len = mapping.value.pattern.path.len();
    let mut relative_path_ends_with_slash_at_pattern_len = false;
    let (match_is_allowed, probably_how) = relative_path.get(pattern_len).map_or_else(
        || (relative_path.len() == pattern_len, Verbatim),
        |b| {
            relative_path_ends_with_slash_at_pattern_len = *b == b'/';
            (relative_path_ends_with_slash_at_pattern_len, Prefix)
        },
    );
    *how = probably_how;
    let pattern_requirement_is_met = !mapping.pattern.mode.contains(gix_glob::pattern::Mode::MUST_BE_DIR)
        || (relative_path_ends_with_slash_at_pattern_len || is_dir);

    if match_is_allowed && pattern_requirement_is_met {
        let dir_or_file = &relative_path[..mapping.value.pattern.path.len()];
        match case {
            Case::Sensitive => mapping.value.pattern.path == dir_or_file,
            Case::Fold => mapping.value.pattern.path.eq_ignore_ascii_case(dir_or_file),
        }
    } else {
        false
    }
}
