use bstr::{BStr, BString, ByteSlice};

use crate::{file::Section, parse::Event, File};

impl File<'_> {
    /// Serialize this type into a `BString` for convenience.
    ///
    /// Note that `to_string()` can also be used, but might not be lossless.
    #[must_use]
    pub fn to_bstring(&self) -> BString {
        let mut buf = Vec::new();
        self.write_to(&mut buf).expect("io error impossible");
        buf.into()
    }

    /// Stream ourselves to the given `out` in order to reproduce this file mostly losslessly
    /// as it was parsed, while writing only sections for which `filter` returns true.
    pub fn write_to_filter(
        &self,
        mut out: &mut dyn std::io::Write,
        mut filter: &mut dyn FnMut(&Section<'_>) -> bool,
    ) -> std::io::Result<()> {
        let nl = self.detect_newline_style();

        {
            for event in self.frontmatter_events.as_ref() {
                event.write_to(&mut out)?;
            }

            if !ends_with_newline(self.frontmatter_events.as_ref(), nl, true) && self.sections.values().any(&mut filter)
            {
                out.write_all(nl)?;
            }
        }

        let mut prev_section_ended_with_newline = true;
        for section_id in &self.section_order {
            if !prev_section_ended_with_newline {
                out.write_all(nl)?;
            }
            let section = self.sections.get(section_id).expect("known section-id");
            if !filter(section) {
                continue;
            }
            section.write_to(&mut out)?;

            prev_section_ended_with_newline = ends_with_newline(section.body.0.as_ref(), nl, false);
            if let Some(post_matter) = self.frontmatter_post_section.get(section_id) {
                if !prev_section_ended_with_newline {
                    out.write_all(nl)?;
                }
                for event in post_matter {
                    event.write_to(&mut out)?;
                }
                prev_section_ended_with_newline = ends_with_newline(post_matter, nl, prev_section_ended_with_newline);
            }
        }

        if !prev_section_ended_with_newline {
            out.write_all(nl)?;
        }

        Ok(())
    }

    /// Stream ourselves to the given `out`, in order to reproduce this file mostly losslessly
    /// as it was parsed.
    pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
        self.write_to_filter(out, &mut |_| true)
    }
}

pub(crate) fn ends_with_newline(e: &[crate::parse::Event<'_>], nl: impl AsRef<[u8]>, default: bool) -> bool {
    if e.is_empty() {
        return default;
    }
    e.iter()
        .rev()
        .take_while(|e| e.to_bstr_lossy().iter().all(u8::is_ascii_whitespace))
        .find_map(|e| e.to_bstr_lossy().contains_str(nl.as_ref()).then_some(true))
        .unwrap_or(false)
}

pub(crate) fn extract_newline<'a>(e: &'a Event<'_>) -> Option<&'a BStr> {
    match e {
        Event::Newline(b) => b.as_ref().into(),
        _ => None,
    }
}

pub(crate) fn platform_newline() -> &'static BStr {
    if cfg!(windows) { "\r\n" } else { "\n" }.into()
}
