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> {
        if text.is_empty() {
            return Err(Error::new(ErrorKind::Empty));
        }

        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.first() == Some(&b'=') {
        (Op::Exact, &input[1..])
    } else if bytes.first() == Some(&b'>') {
        if bytes.get(1) == Some(&b'=') {
            (Op::GreaterEq, &input[2..])
        } else {
            (Op::Greater, &input[1..])
        }
    } else if bytes.first() == Some(&b'<') {
        if bytes.get(1) == Some(&b'=') {
            (Op::LessEq, &input[2..])
        } else {
            (Op::Less, &input[1..])
        }
    } else if bytes.first() == Some(&b'~') {
        (Op::Tilde, &input[1..])
    } else if bytes.first() == 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)
}
