use crate::parse::Error;
use core::fmt::{self, Debug, Display};

pub(crate) enum ErrorKind {
    UnexpectedEnd(Position),
    UnexpectedChar(Position, char),
    UnexpectedCharAfter(Position, char),
    ExpectedCommaFound(Position, char),
    LeadingZero(Position),
    Overflow(Position),
    EmptySegment(Position),
    IllegalCharacter(Position),
    WildcardNotTheOnlyComparator(char),
    UnexpectedAfterWildcard,
    ExcessiveComparators,
}

#[derive(Copy, Clone, Eq, PartialEq)]
pub(crate) enum Position {
    Major,
    Minor,
    Patch,
    Pre,
    Build,
}

#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl std::error::Error for Error {}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match &self.kind {
            ErrorKind::UnexpectedEnd(pos) => {
                write!(formatter, "unexpected end of input while parsing {}", pos)
            }
            ErrorKind::UnexpectedChar(pos, ch) => {
                write!(
                    formatter,
                    "unexpected character {} while parsing {}",
                    QuotedChar(*ch),
                    pos,
                )
            }
            ErrorKind::UnexpectedCharAfter(pos, ch) => {
                write!(
                    formatter,
                    "unexpected character {} after {}",
                    QuotedChar(*ch),
                    pos,
                )
            }
            ErrorKind::ExpectedCommaFound(pos, ch) => {
                write!(
                    formatter,
                    "expected comma after {}, found {}",
                    pos,
                    QuotedChar(*ch),
                )
            }
            ErrorKind::LeadingZero(pos) => {
                write!(formatter, "invalid leading zero in {}", pos)
            }
            ErrorKind::Overflow(pos) => {
                write!(formatter, "value of {} exceeds u64::MAX", pos)
            }
            ErrorKind::EmptySegment(pos) => {
                write!(formatter, "empty identifier segment in {}", pos)
            }
            ErrorKind::IllegalCharacter(pos) => {
                write!(formatter, "unexpected character in {}", pos)
            }
            ErrorKind::WildcardNotTheOnlyComparator(ch) => {
                write!(
                    formatter,
                    "wildcard req ({}) must be the only comparator in the version req",
                    ch,
                )
            }
            ErrorKind::UnexpectedAfterWildcard => {
                formatter.write_str("unexpected character after wildcard in version req")
            }
            ErrorKind::ExcessiveComparators => {
                formatter.write_str("excessive number of version comparators")
            }
        }
    }
}

impl Display for Position {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(match self {
            Position::Major => "major version number",
            Position::Minor => "minor version number",
            Position::Patch => "patch version number",
            Position::Pre => "pre-release identifier",
            Position::Build => "build metadata",
        })
    }
}

impl Debug for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("Error(\"")?;
        Display::fmt(self, formatter)?;
        formatter.write_str("\")")?;
        Ok(())
    }
}

struct QuotedChar(char);

impl Display for QuotedChar {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        // Standard library versions prior to https://github.com/rust-lang/rust/pull/95345
        // print character 0 as '\u{0}'. We prefer '\0' to keep error messages
        // the same across all supported Rust versions.
        if self.0 == '\0' {
            formatter.write_str("'\\0'")
        } else {
            write!(formatter, "{:?}", self.0)
        }
    }
}
