use std::borrow::Cow;

use crate::{name, AssignmentRef, Name, NameRef, StateRef};
use bstr::{BStr, ByteSlice};
use kstring::KStringRef;

/// The kind of attribute that was parsed.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Kind {
    /// A pattern to match paths against
    Pattern(gix_glob::Pattern),
    /// The name of the macro to define, always a valid attribute name
    Macro(Name),
}

mod error {
    use bstr::BString;
    /// The error returned by [`parse::Lines`][crate::parse::Lines].
    #[derive(thiserror::Error, Debug)]
    #[allow(missing_docs)]
    pub enum Error {
        #[error("Line {line_number} has a negative pattern, for literal characters use \\!: {line}")]
        PatternNegation { line_number: usize, line: BString },
        #[error("Attribute in line {line_number} has non-ascii characters or starts with '-': {attribute}")]
        AttributeName { line_number: usize, attribute: BString },
        #[error("Macro in line {line_number} has non-ascii characters or starts with '-': {macro_name}")]
        MacroName { line_number: usize, macro_name: BString },
        #[error("Could not unquote attributes line")]
        Unquote(#[from] gix_quote::ansi_c::undo::Error),
    }
}
pub use error::Error;

/// An iterator over attribute assignments, parsed line by line.
pub struct Lines<'a> {
    lines: bstr::Lines<'a>,
    line_no: usize,
}

/// An iterator over attribute assignments in a single line.
pub struct Iter<'a> {
    attrs: bstr::Fields<'a>,
}

impl<'a> Iter<'a> {
    /// Create a new instance to parse attribute assignments from `input`.
    pub fn new(input: &'a BStr) -> Self {
        Iter { attrs: input.fields() }
    }

    fn parse_attr(&self, attr: &'a [u8]) -> Result<AssignmentRef<'a>, name::Error> {
        let mut tokens = attr.splitn(2, |b| *b == b'=');
        let attr = tokens.next().expect("attr itself").as_bstr();
        let possibly_value = tokens.next();
        let (attr, state) = if attr.first() == Some(&b'-') {
            (&attr[1..], StateRef::Unset)
        } else if attr.first() == Some(&b'!') {
            (&attr[1..], StateRef::Unspecified)
        } else {
            (attr, possibly_value.map_or(StateRef::Set, StateRef::from_bytes))
        };
        Ok(AssignmentRef::new(check_attr(attr)?, state))
    }
}

fn check_attr(attr: &BStr) -> Result<NameRef<'_>, name::Error> {
    fn attr_valid(attr: &BStr) -> bool {
        if attr.first() == Some(&b'-') {
            return false;
        }

        attr.bytes()
            .all(|b| matches!(b, b'-' | b'.' | b'_' | b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9'))
    }

    attr_valid(attr)
        .then(|| NameRef(KStringRef::from_ref(attr.to_str().expect("no illformed utf8"))))
        .ok_or_else(|| name::Error { attribute: attr.into() })
}

impl<'a> Iterator for Iter<'a> {
    type Item = Result<AssignmentRef<'a>, name::Error>;

    fn next(&mut self) -> Option<Self::Item> {
        let attr = self.attrs.next().filter(|a| !a.is_empty())?;
        self.parse_attr(attr).into()
    }
}

/// Instantiation
impl<'a> Lines<'a> {
    /// Create a new instance to parse all attributes in all lines of the input `bytes`.
    pub fn new(bytes: &'a [u8]) -> Self {
        let bom = unicode_bom::Bom::from(bytes);
        Lines {
            lines: bytes[bom.len()..].lines(),
            line_no: 0,
        }
    }
}

impl<'a> Iterator for Lines<'a> {
    type Item = Result<(Kind, Iter<'a>, usize), Error>;

    fn next(&mut self) -> Option<Self::Item> {
        fn skip_blanks(line: &BStr) -> &BStr {
            line.find_not_byteset(BLANKS).map_or(line, |pos| &line[pos..])
        }
        for line in self.lines.by_ref() {
            self.line_no += 1;
            let line = skip_blanks(line.into());
            if line.first() == Some(&b'#') {
                continue;
            }
            match parse_line(line, self.line_no) {
                None => continue,
                Some(res) => return Some(res),
            }
        }
        None
    }
}

fn parse_line(line: &BStr, line_number: usize) -> Option<Result<(Kind, Iter<'_>, usize), Error>> {
    if line.is_empty() {
        return None;
    }

    let (line, attrs): (Cow<'_, _>, _) = if line.starts_with(b"\"") {
        let (unquoted, consumed) = match gix_quote::ansi_c::undo(line) {
            Ok(res) => res,
            Err(err) => return Some(Err(err.into())),
        };
        (unquoted, &line[consumed..])
    } else {
        line.find_byteset(BLANKS)
            .map(|pos| (line[..pos].as_bstr().into(), line[pos..].as_bstr()))
            .unwrap_or((line.into(), [].as_bstr()))
    };

    let kind_res = match line.strip_prefix(b"[attr]") {
        Some(macro_name) => check_attr(macro_name.into())
            .map_err(|err| Error::MacroName {
                line_number,
                macro_name: err.attribute,
            })
            .map(|name| Kind::Macro(name.to_owned())),
        None => {
            let pattern = gix_glob::Pattern::from_bytes(line.as_ref())?;
            if pattern.mode.contains(gix_glob::pattern::Mode::NEGATIVE) {
                Err(Error::PatternNegation {
                    line: line.into_owned(),
                    line_number,
                })
            } else {
                Ok(Kind::Pattern(pattern))
            }
        }
    };
    let kind = match kind_res {
        Ok(kind) => kind,
        Err(err) => return Some(Err(err)),
    };
    Ok((kind, Iter::new(attrs), line_number)).into()
}

const BLANKS: &[u8] = b" \t\r";
