use std::cell::RefCell;
use std::ffi::OsStr;
use std::ops::RangeInclusive;
use std::path::{Component, Path, PathBuf};
use std::rc::Rc;
use std::{fmt, fs};

use rinja::Template;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::{FileName, sym};
use tracing::info;

use crate::clean;
use crate::clean::utils::has_doc_flag;
use crate::docfs::PathError;
use crate::error::Error;
use crate::html::render::Context;
use crate::html::{format, highlight, layout};
use crate::visit::DocVisitor;

pub(crate) fn render(cx: &mut Context<'_>, krate: &clean::Crate) -> Result<(), Error> {
    info!("emitting source files");

    let dst = cx.dst.join("src").join(krate.name(cx.tcx()).as_str());
    cx.shared.ensure_dir(&dst)?;
    let crate_name = krate.name(cx.tcx());
    let crate_name = crate_name.as_str();

    let mut collector =
        SourceCollector { dst, cx, emitted_local_sources: FxHashSet::default(), crate_name };
    collector.visit_crate(krate);
    Ok(())
}

pub(crate) fn collect_local_sources<'tcx>(
    tcx: TyCtxt<'tcx>,
    src_root: &Path,
    krate: &clean::Crate,
) -> FxIndexMap<PathBuf, String> {
    let mut lsc = LocalSourcesCollector { tcx, local_sources: FxIndexMap::default(), src_root };
    lsc.visit_crate(krate);
    lsc.local_sources
}

struct LocalSourcesCollector<'a, 'tcx> {
    tcx: TyCtxt<'tcx>,
    local_sources: FxIndexMap<PathBuf, String>,
    src_root: &'a Path,
}

fn is_real_and_local(span: clean::Span, sess: &Session) -> bool {
    span.cnum(sess) == LOCAL_CRATE && span.filename(sess).is_real()
}

impl LocalSourcesCollector<'_, '_> {
    fn add_local_source(&mut self, item: &clean::Item) {
        let sess = self.tcx.sess;
        let span = item.span(self.tcx);
        let Some(span) = span else { return };
        // skip all synthetic "files"
        if !is_real_and_local(span, sess) {
            return;
        }
        let filename = span.filename(sess);
        let p = if let FileName::Real(file) = filename {
            match file.into_local_path() {
                Some(p) => p,
                None => return,
            }
        } else {
            return;
        };
        if self.local_sources.contains_key(&*p) {
            // We've already emitted this source
            return;
        }

        let href = RefCell::new(PathBuf::new());
        clean_path(
            &self.src_root,
            &p,
            |component| {
                href.borrow_mut().push(component);
            },
            || {
                href.borrow_mut().pop();
            },
        );

        let mut href = href.into_inner().to_string_lossy().into_owned();
        if let Some(c) = href.as_bytes().last()
            && *c != b'/'
        {
            href.push('/');
        }
        let mut src_fname = p.file_name().expect("source has no filename").to_os_string();
        src_fname.push(".html");
        href.push_str(&src_fname.to_string_lossy());
        self.local_sources.insert(p, href);
    }
}

impl DocVisitor<'_> for LocalSourcesCollector<'_, '_> {
    fn visit_item(&mut self, item: &clean::Item) {
        self.add_local_source(item);

        self.visit_item_recur(item)
    }
}

/// Helper struct to render all source code to HTML pages
struct SourceCollector<'a, 'tcx> {
    cx: &'a mut Context<'tcx>,

    /// Root destination to place all HTML output into
    dst: PathBuf,
    emitted_local_sources: FxHashSet<PathBuf>,

    crate_name: &'a str,
}

impl DocVisitor<'_> for SourceCollector<'_, '_> {
    fn visit_item(&mut self, item: &clean::Item) {
        if !self.cx.include_sources {
            return;
        }

        let tcx = self.cx.tcx();
        let span = item.span(tcx);
        let Some(span) = span else { return };
        let sess = tcx.sess;

        // If we're not rendering sources, there's nothing to do.
        // If we're including source files, and we haven't seen this file yet,
        // then we need to render it out to the filesystem.
        if is_real_and_local(span, sess) {
            let filename = span.filename(sess);
            let span = span.inner();
            let pos = sess.source_map().lookup_source_file(span.lo());
            let file_span = span.with_lo(pos.start_pos).with_hi(pos.end_position());
            // If it turns out that we couldn't read this file, then we probably
            // can't read any of the files (generating html output from json or
            // something like that), so just don't include sources for the
            // entire crate. The other option is maintaining this mapping on a
            // per-file basis, but that's probably not worth it...
            self.cx.include_sources = match self.emit_source(&filename, file_span) {
                Ok(()) => true,
                Err(e) => {
                    self.cx.shared.tcx.dcx().span_err(
                        span,
                        format!(
                            "failed to render source code for `{filename}`: {e}",
                            filename = filename.prefer_local(),
                        ),
                    );
                    false
                }
            };
        }

        self.visit_item_recur(item)
    }
}

impl SourceCollector<'_, '_> {
    /// Renders the given filename into its corresponding HTML source file.
    fn emit_source(
        &mut self,
        filename: &FileName,
        file_span: rustc_span::Span,
    ) -> Result<(), Error> {
        let p = match *filename {
            FileName::Real(ref file) => {
                if let Some(local_path) = file.local_path() {
                    local_path.to_path_buf()
                } else {
                    unreachable!("only the current crate should have sources emitted");
                }
            }
            _ => return Ok(()),
        };
        if self.emitted_local_sources.contains(&*p) {
            // We've already emitted this source
            return Ok(());
        }

        let contents = match fs::read_to_string(&p) {
            Ok(contents) => contents,
            Err(e) => {
                return Err(Error::new(e, &p));
            }
        };

        // Remove the utf-8 BOM if any
        let contents = contents.strip_prefix('\u{feff}').unwrap_or(&contents);

        let shared = Rc::clone(&self.cx.shared);
        // Create the intermediate directories
        let cur = RefCell::new(PathBuf::new());
        let root_path = RefCell::new(PathBuf::new());

        clean_path(
            &shared.src_root,
            &p,
            |component| {
                cur.borrow_mut().push(component);
                root_path.borrow_mut().push("..");
            },
            || {
                cur.borrow_mut().pop();
                root_path.borrow_mut().pop();
            },
        );

        let src_fname = p.file_name().expect("source has no filename").to_os_string();
        let mut fname = src_fname.clone();

        let root_path = PathBuf::from("../../").join(root_path.into_inner());
        let mut root_path = root_path.to_string_lossy();
        if let Some(c) = root_path.as_bytes().last()
            && *c != b'/'
        {
            root_path += "/";
        }
        let mut file_path = Path::new(&self.crate_name).join(&*cur.borrow());
        file_path.push(&fname);
        fname.push(".html");
        let mut cur = self.dst.join(cur.into_inner());
        shared.ensure_dir(&cur)?;

        cur.push(&fname);

        let title = format!("{} - source", src_fname.to_string_lossy());
        let desc =
            format!("Source of the Rust file `{}`.", filename.prefer_remapped_unconditionaly());
        let page = layout::Page {
            title: &title,
            css_class: "src",
            root_path: &root_path,
            static_root_path: shared.static_root_path.as_deref(),
            description: &desc,
            resource_suffix: &shared.resource_suffix,
            rust_logo: has_doc_flag(self.cx.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo),
        };
        let v = layout::render(
            &shared.layout,
            &page,
            "",
            |buf: &mut _| {
                let cx = &mut self.cx;
                print_src(
                    buf,
                    contents,
                    file_span,
                    cx,
                    &root_path,
                    highlight::DecorationInfo::default(),
                    SourceContext::Standalone { file_path },
                )
            },
            &shared.style_files,
        );
        shared.fs.write(cur, v)?;
        self.emitted_local_sources.insert(p);
        Ok(())
    }
}

/// Takes a path to a source file and cleans the path to it. This canonicalizes
/// things like ".." to components which preserve the "top down" hierarchy of a
/// static HTML tree. Each component in the cleaned path will be passed as an
/// argument to `f`. The very last component of the path (ie the file name) is ignored.
/// If a `..` is encountered, the `parent` closure will be called to allow the callee to
/// handle it.
pub(crate) fn clean_path<F, P>(src_root: &Path, p: &Path, mut f: F, mut parent: P)
where
    F: FnMut(&OsStr),
    P: FnMut(),
{
    // make it relative, if possible
    let p = p.strip_prefix(src_root).unwrap_or(p);

    let mut iter = p.components().peekable();

    while let Some(c) = iter.next() {
        if iter.peek().is_none() {
            break;
        }

        match c {
            Component::ParentDir => parent(),
            Component::Normal(c) => f(c),
            _ => continue,
        }
    }
}

pub(crate) struct ScrapedInfo<'a> {
    pub(crate) offset: usize,
    pub(crate) name: &'a str,
    pub(crate) url: &'a str,
    pub(crate) title: &'a str,
    pub(crate) locations: String,
    pub(crate) needs_expansion: bool,
}

#[derive(Template)]
#[template(path = "scraped_source.html")]
struct ScrapedSource<'a, Code: std::fmt::Display> {
    info: ScrapedInfo<'a>,
    lines: RangeInclusive<usize>,
    code_html: Code,
}

#[derive(Template)]
#[template(path = "source.html")]
struct Source<Code: std::fmt::Display> {
    lines: RangeInclusive<usize>,
    code_html: Code,
    file_path: Option<(String, String)>,
}

pub(crate) enum SourceContext<'a> {
    Standalone { file_path: PathBuf },
    Embedded(ScrapedInfo<'a>),
}

/// Wrapper struct to render the source code of a file. This will do things like
/// adding line numbers to the left-hand side.
pub(crate) fn print_src(
    mut writer: impl fmt::Write,
    s: &str,
    file_span: rustc_span::Span,
    context: &Context<'_>,
    root_path: &str,
    decoration_info: highlight::DecorationInfo,
    source_context: SourceContext<'_>,
) {
    let current_href = context
        .href_from_span(clean::Span::new(file_span), false)
        .expect("only local crates should have sources emitted");
    let code = format::display_fn(move |fmt| {
        highlight::write_code(
            fmt,
            s,
            Some(highlight::HrefContext { context, file_span, root_path, current_href }),
            Some(decoration_info),
        );
        Ok(())
    });
    let lines = s.lines().count();
    match source_context {
        SourceContext::Standalone { file_path } => Source {
            lines: (1..=lines),
            code_html: code,
            file_path: if let Some(file_name) = file_path.file_name()
                && let Some(file_path) = file_path.parent()
            {
                Some((file_path.display().to_string(), file_name.display().to_string()))
            } else {
                None
            },
        }
        .render_into(&mut writer)
        .unwrap(),
        SourceContext::Embedded(info) => {
            let lines = (1 + info.offset)..=(lines + info.offset);
            ScrapedSource { info, lines, code_html: code }.render_into(&mut writer).unwrap();
        }
    };
}
