use std::fmt::{self, Write};

use rustc_span::Symbol;

/// A builder that allows efficiently and easily constructing the part of a URL
/// after the domain: `nightly/core/str/struct.Bytes.html`.
///
/// This type is a wrapper around the final `String` buffer,
/// but its API is like that of a `Vec` of URL components.
#[derive(Debug)]
pub(crate) struct UrlPartsBuilder {
    buf: String,
}

impl UrlPartsBuilder {
    /// Create an empty buffer.
    pub(crate) fn new() -> Self {
        Self { buf: String::new() }
    }

    /// Create an empty buffer with capacity for the specified number of bytes.
    fn with_capacity_bytes(count: usize) -> Self {
        Self { buf: String::with_capacity(count) }
    }

    /// Create a buffer with one URL component.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```ignore (private-type)
    /// let builder = UrlPartsBuilder::singleton("core");
    /// assert_eq!(builder.finish(), "core");
    /// ```
    ///
    /// Adding more components afterward.
    ///
    /// ```ignore (private-type)
    /// let mut builder = UrlPartsBuilder::singleton("core");
    /// builder.push("str");
    /// builder.push_front("nightly");
    /// assert_eq!(builder.finish(), "nightly/core/str");
    /// ```
    pub(crate) fn singleton(part: &str) -> Self {
        Self { buf: part.to_owned() }
    }

    /// Push a component onto the buffer.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```ignore (private-type)
    /// let mut builder = UrlPartsBuilder::new();
    /// builder.push("core");
    /// builder.push("str");
    /// builder.push("struct.Bytes.html");
    /// assert_eq!(builder.finish(), "core/str/struct.Bytes.html");
    /// ```
    pub(crate) fn push(&mut self, part: &str) {
        if !self.buf.is_empty() {
            self.buf.push('/');
        }
        self.buf.push_str(part);
    }

    /// Push a component onto the buffer, using [`format!`]'s formatting syntax.
    ///
    /// # Examples
    ///
    /// Basic usage (equivalent to the example for [`UrlPartsBuilder::push`]):
    ///
    /// ```ignore (private-type)
    /// let mut builder = UrlPartsBuilder::new();
    /// builder.push("core");
    /// builder.push("str");
    /// builder.push_fmt(format_args!("{}.{}.html", "struct", "Bytes"));
    /// assert_eq!(builder.finish(), "core/str/struct.Bytes.html");
    /// ```
    pub(crate) fn push_fmt(&mut self, args: fmt::Arguments<'_>) {
        if !self.buf.is_empty() {
            self.buf.push('/');
        }
        self.buf.write_fmt(args).unwrap()
    }

    /// Push a component onto the front of the buffer.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```ignore (private-type)
    /// let mut builder = UrlPartsBuilder::new();
    /// builder.push("core");
    /// builder.push("str");
    /// builder.push_front("nightly");
    /// builder.push("struct.Bytes.html");
    /// assert_eq!(builder.finish(), "nightly/core/str/struct.Bytes.html");
    /// ```
    pub(crate) fn push_front(&mut self, part: &str) {
        let is_empty = self.buf.is_empty();
        self.buf.reserve(part.len() + if !is_empty { 1 } else { 0 });
        self.buf.insert_str(0, part);
        if !is_empty {
            self.buf.insert(part.len(), '/');
        }
    }

    /// Get the final `String` buffer.
    pub(crate) fn finish(self) -> String {
        self.buf
    }
}

/// This is just a guess at the average length of a URL part,
/// used for [`String::with_capacity`] calls in the [`FromIterator`]
/// and [`Extend`] impls.
///
/// The value `8` was chosen for two main reasons:
///
/// * It seems like a good guess for the average part length.
/// * jemalloc's size classes are all multiples of eight,
///   which means that the amount of memory it allocates will often match
///   the amount requested, avoiding wasted bytes.
const AVG_PART_LENGTH: usize = 8;

impl<'a> FromIterator<&'a str> for UrlPartsBuilder {
    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
        let iter = iter.into_iter();
        let mut builder = Self::with_capacity_bytes(AVG_PART_LENGTH * iter.size_hint().0);
        iter.for_each(|part| builder.push(part));
        builder
    }
}

impl<'a> Extend<&'a str> for UrlPartsBuilder {
    fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
        let iter = iter.into_iter();
        self.buf.reserve(AVG_PART_LENGTH * iter.size_hint().0);
        iter.for_each(|part| self.push(part));
    }
}

impl FromIterator<Symbol> for UrlPartsBuilder {
    fn from_iter<T: IntoIterator<Item = Symbol>>(iter: T) -> Self {
        // This code has to be duplicated from the `&str` impl because of
        // `Symbol::as_str`'s lifetimes.
        let iter = iter.into_iter();
        let mut builder = Self::with_capacity_bytes(AVG_PART_LENGTH * iter.size_hint().0);
        iter.for_each(|part| builder.push(part.as_str()));
        builder
    }
}

impl Extend<Symbol> for UrlPartsBuilder {
    fn extend<T: IntoIterator<Item = Symbol>>(&mut self, iter: T) {
        // This code has to be duplicated from the `&str` impl because of
        // `Symbol::as_str`'s lifetimes.
        let iter = iter.into_iter();
        self.buf.reserve(AVG_PART_LENGTH * iter.size_hint().0);
        iter.for_each(|part| self.push(part.as_str()));
    }
}

#[cfg(test)]
mod tests;
