use crate::backport::*;
use crate::error::{ErrorKind, Position};
use crate::identifier::Identifier;
use crate::{BuildMetadata, Comparator, Op, Prerelease, Version, VersionReq};
use core::str::FromStr;

/// Error parsing a SemVer version or version requirement.
///
/// # Example
///
/// ```
/// use semver::Version;
///
/// fn main() {
///     let err = Version::parse("1.q.r").unwrap_err();
///
///     // "unexpected character 'q' while parsing minor version number"
///     eprintln!("{}", err);
/// }
/// ```
pub struct Error {
    pub(crate) kind: ErrorKind,
}

impl FromStr for Version {
    type Err = Error;

    fn from_str(text: &str) -> Result<Self, Self::Err> {
        let mut pos = Position::Major;
        let (major, text) = numeric_identifier(text, pos)?;
        let text = dot(text, pos)?;

        pos = Position::Minor;
        let (minor, text) = numeric_identifier(text, pos)?;
        let text = dot(text, pos)?;

        pos = Position::Patch;
        let (patch, text) = numeric_identifier(text, pos)?;

        if text.is_empty() {
            return Ok(Version::new(major, minor, patch));
        }

        let (pre, text) = if let Some(text) = text.strip_prefix('-') {
            pos = Position::Pre;
            let (pre, text) = prerelease_identifier(text)?;
            if pre.is_empty() {
                return Err(Error::new(ErrorKind::EmptySegment(pos)));
            }
            (pre, text)
        } else {
            (Prerelease::EMPTY, text)
        };

        let (build, text) = if let Some(text) = text.strip_prefix('+') {
            pos = Position::Build;
            let (build, text) = build_identifier(text)?;
            if build.is_empty() {
                return Err(Error::new(ErrorKind::EmptySegment(pos)));
            }
            (build, text)
        } else {
            (BuildMetadata::EMPTY, text)
        };

        if let Some(unexpected) = text.chars().next() {
            return Err(Error::new(ErrorKind::UnexpectedCharAfter(pos, unexpected)));
        }

        Ok(Version {
            major,
            minor,
            patch,
            pre,
            build,
        })
    }
}

impl FromStr for VersionReq {
    type Err = Error;

    fn from_str(text: &str) -> Result<Self, Self::Err> {
        let text = text.trim_start_matches(' ');
        if let Some((ch, text)) = wildcard(text) {
            let rest = text.trim_start_matches(' ');
            if rest.is_empty() {
                #[cfg(not(no_const_vec_new))]
                return Ok(VersionReq::STAR);
                #[cfg(no_const_vec_new)] // rustc <1.39
                return Ok(VersionReq {
                    comparators: Vec::new(),
                });
            } else if rest.starts_with(',') {
                return Err(Error::new(ErrorKind::WildcardNotTheOnlyComparator(ch)));
            } else {
                return Err(Error::new(ErrorKind::UnexpectedAfterWildcard));
            }
        }

        let depth = 0;
        let mut comparators = Vec::new();
        let len = version_req(text, &mut comparators, depth)?;
        unsafe { comparators.set_len(len) }
        Ok(VersionReq { comparators })
    }
}

impl FromStr for Comparator {
    type Err = Error;

    fn from_str(text: &str) -> Result<Self, Self::Err> {
        let text = text.trim_start_matches(' ');
        let (comparator, pos, rest) = comparator(text)?;
        if !rest.is_empty() {
            let unexpected = rest.chars().next().unwrap();
            return Err(Error::new(ErrorKind::UnexpectedCharAfter(pos, unexpected)));
        }
        Ok(comparator)
    }
}

impl FromStr for Prerelease {
    type Err = Error;

    fn from_str(text: &str) -> Result<Self, Self::Err> {
        let (pre, rest) = prerelease_identifier(text)?;
        if !rest.is_empty() {
            return Err(Error::new(ErrorKind::IllegalCharacter(Position::Pre)));
        }
        Ok(pre)
    }
}

impl FromStr for BuildMetadata {
    type Err = Error;

    fn from_str(text: &str) -> Result<Self, Self::Err> {
        let (build, rest) = build_identifier(text)?;
        if !rest.is_empty() {
            return Err(Error::new(ErrorKind::IllegalCharacter(Position::Build)));
        }
        Ok(build)
    }
}

impl Error {
    fn new(kind: ErrorKind) -> Self {
        Error { kind }
    }
}

impl Op {
    const DEFAULT: Self = Op::Caret;
}

fn numeric_identifier(input: &str, pos: Position) -> Result<(u64, &str), Error> {
    let mut len = 0;
    let mut value = 0u64;

    while let Some(&digit) = input.as_bytes().get(len) {
        if digit < b'0' || digit > b'9' {
            break;
        }
        if value == 0 && len > 0 {
            return Err(Error::new(ErrorKind::LeadingZero(pos)));
        }
        match value
            .checked_mul(10)
            .and_then(|value| value.checked_add((digit - b'0') as u64))
        {
            Some(sum) => value = sum,
            None => return Err(Error::new(ErrorKind::Overflow(pos))),
        }
        len += 1;
    }

    if len > 0 {
        Ok((value, &input[len..]))
    } else if let Some(unexpected) = input[len..].chars().next() {
        Err(Error::new(ErrorKind::UnexpectedChar(pos, unexpected)))
    } else {
        Err(Error::new(ErrorKind::UnexpectedEnd(pos)))
    }
}

fn wildcard(input: &str) -> Option<(char, &str)> {
    if let Some(rest) = input.strip_prefix('*') {
        Some(('*', rest))
    } else if let Some(rest) = input.strip_prefix('x') {
        Some(('x', rest))
    } else if let Some(rest) = input.strip_prefix('X') {
        Some(('X', rest))
    } else {
        None
    }
}

fn dot(input: &str, pos: Position) -> Result<&str, Error> {
    if let Some(rest) = input.strip_prefix('.') {
        Ok(rest)
    } else if let Some(unexpected) = input.chars().next() {
        Err(Error::new(ErrorKind::UnexpectedCharAfter(pos, unexpected)))
    } else {
        Err(Error::new(ErrorKind::UnexpectedEnd(pos)))
    }
}

fn prerelease_identifier(input: &str) -> Result<(Prerelease, &str), Error> {
    let (string, rest) = identifier(input, Position::Pre)?;
    let identifier = unsafe { Identifier::new_unchecked(string) };
    Ok((Prerelease { identifier }, rest))
}

fn build_identifier(input: &str) -> Result<(BuildMetadata, &str), Error> {
    let (string, rest) = identifier(input, Position::Build)?;
    let identifier = unsafe { Identifier::new_unchecked(string) };
    Ok((BuildMetadata { identifier }, rest))
}

fn identifier(input: &str, pos: Position) -> Result<(&str, &str), Error> {
    let mut accumulated_len = 0;
    let mut segment_len = 0;
    let mut segment_has_nondigit = false;

    loop {
        match input.as_bytes().get(accumulated_len + segment_len) {
            Some(b'A'..=b'Z') | Some(b'a'..=b'z') | Some(b'-') => {
                segment_len += 1;
                segment_has_nondigit = true;
            }
            Some(b'0'..=b'9') => {
                segment_len += 1;
            }
            boundary => {
                if segment_len == 0 {
                    if accumulated_len == 0 && boundary != Some(&b'.') {
                        return Ok(("", input));
                    } else {
                        return Err(Error::new(ErrorKind::EmptySegment(pos)));
                    }
                }
                if pos == Position::Pre
                    && segment_len > 1
                    && !segment_has_nondigit
                    && input[accumulated_len..].starts_with('0')
                {
                    return Err(Error::new(ErrorKind::LeadingZero(pos)));
                }
                accumulated_len += segment_len;
                if boundary == Some(&b'.') {
                    accumulated_len += 1;
                    segment_len = 0;
                    segment_has_nondigit = false;
                } else {
                    return Ok(input.split_at(accumulated_len));
                }
            }
        }
    }
}

fn op(input: &str) -> (Op, &str) {
    let bytes = input.as_bytes();
    if bytes.get(0) == Some(&b'=') {
        (Op::Exact, &input[1..])
    } else if bytes.get(0) == Some(&b'>') {
        if bytes.get(1) == Some(&b'=') {
            (Op::GreaterEq, &input[2..])
        } else {
            (Op::Greater, &input[1..])
        }
    } else if bytes.get(0) == Some(&b'<') {
        if bytes.get(1) == Some(&b'=') {
            (Op::LessEq, &input[2..])
        } else {
            (Op::Less, &input[1..])
        }
    } else if bytes.get(0) == Some(&b'~') {
        (Op::Tilde, &input[1..])
    } else if bytes.get(0) == Some(&b'^') {
        (Op::Caret, &input[1..])
    } else {
        (Op::DEFAULT, input)
    }
}

fn comparator(input: &str) -> Result<(Comparator, Position, &str), Error> {
    let (mut op, text) = op(input);
    let default_op = input.len() == text.len();
    let text = text.trim_start_matches(' ');

    let mut pos = Position::Major;
    let (major, text) = numeric_identifier(text, pos)?;
    let mut has_wildcard = false;

    let (minor, text) = if let Some(text) = text.strip_prefix('.') {
        pos = Position::Minor;
        if let Some((_, text)) = wildcard(text) {
            has_wildcard = true;
            if default_op {
                op = Op::Wildcard;
            }
            (None, text)
        } else {
            let (minor, text) = numeric_identifier(text, pos)?;
            (Some(minor), text)
        }
    } else {
        (None, text)
    };

    let (patch, text) = if let Some(text) = text.strip_prefix('.') {
        pos = Position::Patch;
        if let Some((_, text)) = wildcard(text) {
            if default_op {
                op = Op::Wildcard;
            }
            (None, text)
        } else if has_wildcard {
            return Err(Error::new(ErrorKind::UnexpectedAfterWildcard));
        } else {
            let (patch, text) = numeric_identifier(text, pos)?;
            (Some(patch), text)
        }
    } else {
        (None, text)
    };

    let (pre, text) = if patch.is_some() && text.starts_with('-') {
        pos = Position::Pre;
        let text = &text[1..];
        let (pre, text) = prerelease_identifier(text)?;
        if pre.is_empty() {
            return Err(Error::new(ErrorKind::EmptySegment(pos)));
        }
        (pre, text)
    } else {
        (Prerelease::EMPTY, text)
    };

    let text = if patch.is_some() && text.starts_with('+') {
        pos = Position::Build;
        let text = &text[1..];
        let (build, text) = build_identifier(text)?;
        if build.is_empty() {
            return Err(Error::new(ErrorKind::EmptySegment(pos)));
        }
        text
    } else {
        text
    };

    let text = text.trim_start_matches(' ');

    let comparator = Comparator {
        op,
        major,
        minor,
        patch,
        pre,
    };

    Ok((comparator, pos, text))
}

fn version_req(input: &str, out: &mut Vec<Comparator>, depth: usize) -> Result<usize, Error> {
    let (comparator, pos, text) = match comparator(input) {
        Ok(success) => success,
        Err(mut error) => {
            if let Some((ch, mut rest)) = wildcard(input) {
                rest = rest.trim_start_matches(' ');
                if rest.is_empty() || rest.starts_with(',') {
                    error.kind = ErrorKind::WildcardNotTheOnlyComparator(ch);
                }
            }
            return Err(error);
        }
    };

    if text.is_empty() {
        out.reserve_exact(depth + 1);
        unsafe { out.as_mut_ptr().add(depth).write(comparator) }
        return Ok(depth + 1);
    }

    let text = if let Some(text) = text.strip_prefix(',') {
        text.trim_start_matches(' ')
    } else {
        let unexpected = text.chars().next().unwrap();
        return Err(Error::new(ErrorKind::ExpectedCommaFound(pos, unexpected)));
    };

    const MAX_COMPARATORS: usize = 32;
    if depth + 1 == MAX_COMPARATORS {
        return Err(Error::new(ErrorKind::ExcessiveComparators));
    }

    // Recurse to collect parsed Comparator objects on the stack. We perform a
    // single allocation to allocate exactly the right sized Vec only once the
    // total number of comparators is known.
    let len = version_req(text, out, depth + 1)?;
    unsafe { out.as_mut_ptr().add(depth).write(comparator) }
    Ok(len)
}
