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) short_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
}
