use crate::{BuildMetadata, Comparator, Op, Prerelease, Version, VersionReq};
use core::fmt::{self, Alignment, Debug, Display, Write};

impl Display for Version {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        let do_display = |formatter: &mut fmt::Formatter| -> fmt::Result {
            write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)?;
            if !self.pre.is_empty() {
                write!(formatter, "-{}", self.pre)?;
            }
            if !self.build.is_empty() {
                write!(formatter, "+{}", self.build)?;
            }
            Ok(())
        };

        let do_len = || -> usize {
            digits(self.major)
                + 1
                + digits(self.minor)
                + 1
                + digits(self.patch)
                + !self.pre.is_empty() as usize
                + self.pre.len()
                + !self.build.is_empty() as usize
                + self.build.len()
        };

        pad(formatter, do_display, do_len)
    }
}

impl Display for VersionReq {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        if self.comparators.is_empty() {
            return formatter.write_str("*");
        }
        for (i, comparator) in self.comparators.iter().enumerate() {
            if i > 0 {
                formatter.write_str(", ")?;
            }
            write!(formatter, "{}", comparator)?;
        }
        Ok(())
    }
}

impl Display for Comparator {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        let op = match self.op {
            Op::Exact => "=",
            Op::Greater => ">",
            Op::GreaterEq => ">=",
            Op::Less => "<",
            Op::LessEq => "<=",
            Op::Tilde => "~",
            Op::Caret => "^",
            Op::Wildcard => "",
            #[cfg(no_non_exhaustive)]
            Op::__NonExhaustive => unreachable!(),
        };
        formatter.write_str(op)?;
        write!(formatter, "{}", self.major)?;
        if let Some(minor) = &self.minor {
            write!(formatter, ".{}", minor)?;
            if let Some(patch) = &self.patch {
                write!(formatter, ".{}", patch)?;
                if !self.pre.is_empty() {
                    write!(formatter, "-{}", self.pre)?;
                }
            } else if self.op == Op::Wildcard {
                formatter.write_str(".*")?;
            }
        } else if self.op == Op::Wildcard {
            formatter.write_str(".*")?;
        }
        Ok(())
    }
}

impl Display for Prerelease {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(self.as_str())
    }
}

impl Display for BuildMetadata {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(self.as_str())
    }
}

impl Debug for Version {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        let mut debug = formatter.debug_struct("Version");
        debug
            .field("major", &self.major)
            .field("minor", &self.minor)
            .field("patch", &self.patch);
        if !self.pre.is_empty() {
            debug.field("pre", &self.pre);
        }
        if !self.build.is_empty() {
            debug.field("build", &self.build);
        }
        debug.finish()
    }
}

impl Debug for Prerelease {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "Prerelease(\"{}\")", self)
    }
}

impl Debug for BuildMetadata {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "BuildMetadata(\"{}\")", self)
    }
}

fn pad(
    formatter: &mut fmt::Formatter,
    do_display: impl FnOnce(&mut fmt::Formatter) -> fmt::Result,
    do_len: impl FnOnce() -> usize,
) -> fmt::Result {
    let min_width = match formatter.width() {
        Some(min_width) => min_width,
        None => return do_display(formatter),
    };

    let len = do_len();
    if len >= min_width {
        return do_display(formatter);
    }

    let default_align = Alignment::Left;
    let align = formatter.align().unwrap_or(default_align);
    let padding = min_width - len;
    let (pre_pad, post_pad) = match align {
        Alignment::Left => (0, padding),
        Alignment::Right => (padding, 0),
        Alignment::Center => (padding / 2, (padding + 1) / 2),
    };

    let fill = formatter.fill();
    for _ in 0..pre_pad {
        formatter.write_char(fill)?;
    }

    do_display(formatter)?;

    for _ in 0..post_pad {
        formatter.write_char(fill)?;
    }
    Ok(())
}

fn digits(val: u64) -> usize {
    if val < 10 {
        1
    } else {
        1 + digits(val / 10)
    }
}
