//! Standalone markdown rendering.
//!
//! For the (much more common) case of rendering markdown in doc-comments, see
//! [crate::html::markdown].
//!
//! This is used when [rendering a markdown file to an html file][docs], without processing
//! rust source code.
//!
//! [docs]: https://doc.rust-lang.org/stable/rustdoc/#using-standalone-markdown-files

use std::fmt::Write as _;
use std::fs::{File, create_dir_all, read_to_string};
use std::io::prelude::*;
use std::path::Path;

use rustc_span::edition::Edition;

use crate::config::RenderOptions;
use crate::html::escape::Escape;
use crate::html::markdown;
use crate::html::markdown::{ErrorCodes, HeadingOffset, IdMap, Markdown, MarkdownWithToc};

/// Separate any lines at the start of the file that begin with `# ` or `%`.
fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) {
    let mut metadata = Vec::new();
    let mut count = 0;

    for line in s.lines() {
        if line.starts_with("# ") || line.starts_with('%') {
            // trim the whitespace after the symbol
            metadata.push(line[1..].trim_start());
            count += line.len() + 1;
        } else {
            return (metadata, &s[count..]);
        }
    }

    // if we're here, then all lines were metadata `# ` or `%` lines.
    (metadata, "")
}

/// Render `input` (e.g., "foo.md") into an HTML file in `output`
/// (e.g., output = "bar" => "bar/foo.html").
///
/// Requires session globals to be available, for symbol interning.
pub(crate) fn render_and_write<P: AsRef<Path>>(
    input: P,
    options: RenderOptions,
    edition: Edition,
) -> Result<(), String> {
    if let Err(e) = create_dir_all(&options.output) {
        return Err(format!("{output}: {e}", output = options.output.display()));
    }

    let input = input.as_ref();
    let mut output = options.output;
    output.push(input.file_name().unwrap());
    output.set_extension("html");

    let mut css = String::new();
    for name in &options.markdown_css {
        write!(css, r#"<link rel="stylesheet" href="{name}">"#)
            .expect("Writing to a String can't fail");
    }

    let input_str =
        read_to_string(input).map_err(|err| format!("{input}: {err}", input = input.display()))?;
    let playground_url = options.markdown_playground_url.or(options.playground_url);
    let playground = playground_url.map(|url| markdown::Playground { crate_name: None, url });

    let mut out =
        File::create(&output).map_err(|e| format!("{output}: {e}", output = output.display()))?;

    let (metadata, text) = extract_leading_metadata(&input_str);
    if metadata.is_empty() {
        return Err("invalid markdown file: no initial lines starting with `# ` or `%`".to_owned());
    }
    let title = metadata[0];

    let mut ids = IdMap::new();
    let error_codes = ErrorCodes::from(options.unstable_features.is_nightly_build());
    let text = if !options.markdown_no_toc {
        MarkdownWithToc {
            content: text,
            links: &[],
            ids: &mut ids,
            error_codes,
            edition,
            playground: &playground,
        }
        .into_string()
    } else {
        Markdown {
            content: text,
            links: &[],
            ids: &mut ids,
            error_codes,
            edition,
            playground: &playground,
            heading_offset: HeadingOffset::H1,
        }
        .into_string()
    };

    let err = write!(
        &mut out,
        r#"<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <title>{title}</title>

    {css}
    {in_header}
</head>
<body class="rustdoc">
    <!--[if lte IE 8]>
    <div class="warning">
        This old browser is unsupported and will most likely display funky
        things.
    </div>
    <![endif]-->

    {before_content}
    <h1 class="title">{title}</h1>
    {text}
    {after_content}
</body>
</html>"#,
        title = Escape(title),
        css = css,
        in_header = options.external_html.in_header,
        before_content = options.external_html.before_content,
        text = text,
        after_content = options.external_html.after_content,
    );

    match err {
        Err(e) => Err(format!("cannot write to `{output}`: {e}", output = output.display())),
        Ok(_) => Ok(()),
    }
}
