use std::fmt::Display;
use std::path::PathBuf;

use askama::Template;
use rustc_data_structures::fx::FxIndexMap;

use super::static_files::{STATIC_FILES, StaticFiles};
use crate::externalfiles::ExternalHtml;
use crate::html::render::{StylePath, ensure_trailing_slash};

#[cfg(test)]
mod tests;

pub(crate) struct Layout {
    pub(crate) logo: String,
    pub(crate) favicon: String,
    pub(crate) external_html: ExternalHtml,
    pub(crate) default_settings: FxIndexMap<String, String>,
    pub(crate) krate: String,
    pub(crate) krate_version: String,
    /// The given user css file which allow to customize the generated
    /// documentation theme.
    pub(crate) css_file_extension: Option<PathBuf>,
    /// If true, then scrape-examples.js will be included in the output HTML file
    pub(crate) scrape_examples_extension: bool,
}

pub(crate) struct Page<'a> {
    pub(crate) title: &'a str,
    pub(crate) css_class: &'a str,
    pub(crate) root_path: &'a str,
    pub(crate) static_root_path: Option<&'a str>,
    pub(crate) description: &'a str,
    pub(crate) resource_suffix: &'a str,
    pub(crate) rust_logo: bool,
}

impl Page<'_> {
    pub(crate) fn get_static_root_path(&self) -> String {
        match self.static_root_path {
            Some(s) => s.to_string(),
            None => format!("{}static.files/", self.root_path),
        }
    }
}

#[derive(Template)]
#[template(path = "page.html")]
struct PageLayout<'a> {
    static_root_path: String,
    page: &'a Page<'a>,
    layout: &'a Layout,

    files: &'static StaticFiles,

    themes: Vec<String>,
    sidebar: String,
    content: String,
    rust_channel: &'static str,
    pub(crate) rustdoc_version: &'a str,
    // same as layout.krate, except on top-level pages like
    // Settings, Help, All Crates, and About Scraped Examples,
    // where these things instead give Rustdoc name and version.
    //
    // These are separate from the variables used for the search
    // engine, because "Rustdoc" isn't necessarily a crate in
    // the current workspace.
    display_krate: &'a str,
    display_krate_with_trailing_slash: String,
    display_krate_version_number: &'a str,
    display_krate_version_extra: &'a str,
}

impl PageLayout<'_> {
    /// See [`may_remove_crossorigin`].
    fn static_root_path_may_remove_crossorigin(&self) -> bool {
        may_remove_crossorigin(&self.static_root_path)
    }
}

pub(crate) use crate::html::render::sidebar::filters;

pub(crate) fn render<T: Display, S: Display>(
    layout: &Layout,
    page: &Page<'_>,
    sidebar: S,
    t: T,
    style_files: &[StylePath],
) -> String {
    let rustdoc_version = rustc_interface::util::version_str!().unwrap_or("unknown version");

    let (display_krate, display_krate_version, display_krate_with_trailing_slash) =
        if page.root_path == "./" {
            // top level pages use Rust branding
            ("Rustdoc", rustdoc_version, String::new())
        } else {
            let display_krate_with_trailing_slash =
                ensure_trailing_slash(&layout.krate).to_string();
            (&layout.krate[..], &layout.krate_version[..], display_krate_with_trailing_slash)
        };
    let static_root_path = page.get_static_root_path();

    // bootstrap passes in parts of the version separated by tabs, but other stuff might use spaces
    let (display_krate_version_number, display_krate_version_extra) =
        display_krate_version.split_once([' ', '\t']).unwrap_or((display_krate_version, ""));

    let mut themes: Vec<String> = style_files.iter().map(|s| s.basename().unwrap()).collect();
    themes.sort();

    let content = t.to_string(); // Note: This must happen before making the sidebar.
    let sidebar = sidebar.to_string();
    PageLayout {
        static_root_path,
        page,
        layout,
        files: &STATIC_FILES,
        themes,
        sidebar,
        content,
        display_krate,
        display_krate_with_trailing_slash,
        display_krate_version_number,
        display_krate_version_extra,
        rust_channel: *crate::clean::utils::RUSTDOC_VERSION,
        rustdoc_version,
    }
    .render()
    .unwrap()
}

pub(crate) fn redirect(url: &str) -> String {
    // <script> triggers a redirect before refresh, so this is fine.
    format!(
        r##"<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="refresh" content="0;URL={url}">
    <title>Redirection</title>
</head>
<body>
    <p>Redirecting to <a href="{url}">{url}</a>...</p>
    <script>location.replace("{url}" + location.search + location.hash);</script>
</body>
</html>"##,
    )
}

/// Conservatively determines if `href` is relative to the current origin,
/// so that `crossorigin` may be safely removed from `<link>` elements.
pub(crate) fn may_remove_crossorigin(href: &str) -> bool {
    // Reject scheme-relative URLs (`//example.com/`).
    if href.starts_with("//") {
        return false;
    }
    // URL is interpreted as having a scheme iff: it starts with an ascii alpha, and only
    // contains ascii alphanumeric or `+` `-` `.` up to the `:`.
    // https://url.spec.whatwg.org/#url-parsing
    let has_scheme = href.split_once(':').is_some_and(|(scheme, _rest)| {
        let mut chars = scheme.chars();
        chars.next().is_some_and(|c| c.is_ascii_alphabetic())
            && chars.all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '-' || c == '.')
    });
    // Reject anything with a scheme (`http:`, etc.).
    !has_scheme
}
