use rustc::lint as lint;
use rustc::hir;
use rustc::hir::def::Def;
use rustc::ty;
use syntax;
use syntax::ast::{self, Ident, NodeId};
use syntax::feature_gate::UnstableFeatures;
use syntax::symbol::Symbol;
use syntax_pos::DUMMY_SP;

use std::ops::Range;

use core::DocContext;
use fold::DocFolder;
use html::markdown::markdown_links;

use clean::*;
use passes::{look_for_tests, Pass};
use super::span_of_attrs;

pub const COLLECT_INTRA_DOC_LINKS: Pass =
    Pass::early("collect-intra-doc-links", collect_intra_doc_links,
                "reads a crate's documentation to resolve intra-doc-links");

pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext) -> Crate {
    if !UnstableFeatures::from_environment().is_nightly_build() {
        krate
    } else {
        let mut coll = LinkCollector::new(cx);

        coll.fold_crate(krate)
    }
}

#[derive(Debug)]
enum PathKind {
    /// Either a value or type, but not a macro
    Unknown,
    /// Macro
    Macro,
    /// Values, functions, consts, statics (everything in the value namespace)
    Value,
    /// Types, traits (everything in the type namespace)
    Type,
}

struct LinkCollector<'a, 'tcx: 'a, 'rcx: 'a> {
    cx: &'a DocContext<'a, 'tcx, 'rcx>,
    mod_ids: Vec<NodeId>,
    is_nightly_build: bool,
}

impl<'a, 'tcx, 'rcx> LinkCollector<'a, 'tcx, 'rcx> {
    fn new(cx: &'a DocContext<'a, 'tcx, 'rcx>) -> Self {
        LinkCollector {
            cx,
            mod_ids: Vec::new(),
            is_nightly_build: UnstableFeatures::from_environment().is_nightly_build(),
        }
    }

    /// Resolve a given string as a path, along with whether or not it is
    /// in the value namespace. Also returns an optional URL fragment in the case
    /// of variants and methods.
    fn resolve(&self,
               path_str: &str,
               is_val: bool,
               current_item: &Option<String>,
               parent_id: Option<NodeId>)
        -> Result<(Def, Option<String>), ()>
    {
        let cx = self.cx;

        // In case we're in a module, try to resolve the relative
        // path.
        if let Some(id) = parent_id.or(self.mod_ids.last().cloned()) {
            // FIXME: `with_scope` requires the `NodeId` of a module.
            let result = cx.resolver.borrow_mut()
                                    .with_scope(id,
                |resolver| {
                    resolver.resolve_str_path_error(DUMMY_SP,
                                                    &path_str, is_val)
            });

            if let Ok(result) = result {
                // In case this is a trait item, skip the
                // early return and try looking for the trait.
                let value = match result.def {
                    Def::Method(_) | Def::AssociatedConst(_) => true,
                    Def::AssociatedTy(_) => false,
                    Def::Variant(_) => return handle_variant(cx, result.def),
                    // Not a trait item; just return what we found.
                    _ => return Ok((result.def, None))
                };

                if value != is_val {
                    return Err(())
                }
            } else if let Some(prim) = is_primitive(path_str, is_val) {
                return Ok((prim, Some(path_str.to_owned())))
            } else {
                // If resolution failed, it may still be a method
                // because methods are not handled by the resolver
                // If so, bail when we're not looking for a value.
                if !is_val {
                    return Err(())
                }
            }

            // Try looking for methods and associated items.
            let mut split = path_str.rsplitn(2, "::");
            let item_name = if let Some(first) = split.next() {
                first
            } else {
                return Err(())
            };

            let mut path = if let Some(second) = split.next() {
                second.to_owned()
            } else {
                return Err(())
            };

            if path == "self" || path == "Self" {
                if let Some(name) = current_item.as_ref() {
                    path = name.clone();
                }
            }

            // FIXME: `with_scope` requires the `NodeId` of a module.
            let ty = cx.resolver.borrow_mut()
                                .with_scope(id,
                |resolver| {
                    resolver.resolve_str_path_error(DUMMY_SP, &path, false)
            })?;
            match ty.def {
                Def::Struct(did) | Def::Union(did) | Def::Enum(did) | Def::TyAlias(did) => {
                    let item = cx.tcx.inherent_impls(did)
                                     .iter()
                                     .flat_map(|imp| cx.tcx.associated_items(*imp))
                                     .find(|item| item.ident.name == item_name);
                    if let Some(item) = item {
                        let out = match item.kind {
                            ty::AssociatedKind::Method if is_val => "method",
                            ty::AssociatedKind::Const if is_val => "associatedconstant",
                            _ => return Err(())
                        };
                        Ok((ty.def, Some(format!("{}.{}", out, item_name))))
                    } else {
                        match cx.tcx.type_of(did).sty {
                            ty::Adt(def, _) => {
                                if let Some(item) = if def.is_enum() {
                                    def.all_fields().find(|item| item.ident.name == item_name)
                                } else {
                                    def.non_enum_variant()
                                       .fields
                                       .iter()
                                       .find(|item| item.ident.name == item_name)
                                } {
                                    Ok((ty.def,
                                        Some(format!("{}.{}",
                                                     if def.is_enum() {
                                                         "variant"
                                                     } else {
                                                         "structfield"
                                                     },
                                                     item.ident))))
                                } else {
                                    Err(())
                                }
                            }
                            _ => Err(()),
                        }
                    }
                }
                Def::Trait(did) => {
                    let item = cx.tcx.associated_item_def_ids(did).iter()
                                 .map(|item| cx.tcx.associated_item(*item))
                                 .find(|item| item.ident.name == item_name);
                    if let Some(item) = item {
                        let kind = match item.kind {
                            ty::AssociatedKind::Const if is_val => "associatedconstant",
                            ty::AssociatedKind::Type if !is_val => "associatedtype",
                            ty::AssociatedKind::Method if is_val => {
                                if item.defaultness.has_value() {
                                    "method"
                                } else {
                                    "tymethod"
                                }
                            }
                            _ => return Err(())
                        };

                        Ok((ty.def, Some(format!("{}.{}", kind, item_name))))
                    } else {
                        Err(())
                    }
                }
                _ => Err(())
            }
        } else {
            Err(())
        }
    }
}

impl<'a, 'tcx, 'rcx> DocFolder for LinkCollector<'a, 'tcx, 'rcx> {
    fn fold_item(&mut self, mut item: Item) -> Option<Item> {
        let item_node_id = if item.is_mod() {
            if let Some(id) = self.cx.tcx.hir().as_local_node_id(item.def_id) {
                Some(id)
            } else {
                debug!("attempting to fold on a non-local item: {:?}", item);
                return self.fold_item_recur(item);
            }
        } else {
            None
        };

        // FIXME: get the resolver to work with non-local resolve scopes.
        let parent_node = self.cx.as_local_node_id(item.def_id).and_then(|node_id| {
            // FIXME: this fails hard for impls in non-module scope, but is necessary for the
            // current `resolve()` implementation.
            match self.cx.tcx.hir().get_module_parent_node(node_id) {
                id if id != node_id => Some(id),
                _ => None,
            }
        });

        if parent_node.is_some() {
            debug!("got parent node for {} {:?}, id {:?}", item.type_(), item.name, item.def_id);
        }

        let current_item = match item.inner {
            ModuleItem(..) => {
                if item.attrs.inner_docs {
                    if item_node_id.unwrap() != NodeId::from_u32(0) {
                        item.name.clone()
                    } else {
                        None
                    }
                } else {
                    match parent_node.or(self.mod_ids.last().cloned()) {
                        Some(parent) if parent != NodeId::from_u32(0) => {
                            // FIXME: can we pull the parent module's name from elsewhere?
                            Some(self.cx.tcx.hir().name(parent).to_string())
                        }
                        _ => None,
                    }
                }
            }
            ImplItem(Impl { ref for_, .. }) => {
                for_.def_id().map(|did| self.cx.tcx.item_name(did).to_string())
            }
            // we don't display docs on `extern crate` items anyway, so don't process them.
            ExternCrateItem(..) => return self.fold_item_recur(item),
            ImportItem(Import::Simple(ref name, ..)) => Some(name.clone()),
            MacroItem(..) => None,
            _ => item.name.clone(),
        };

        if item.is_mod() && item.attrs.inner_docs {
            self.mod_ids.push(item_node_id.unwrap());
        }

        let cx = self.cx;
        let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new);

        look_for_tests(&cx, &dox, &item, true);

        if !self.is_nightly_build {
            return None;
        }

        for (ori_link, link_range) in markdown_links(&dox) {
            // Bail early for real links.
            if ori_link.contains('/') {
                continue;
            }
            let link = ori_link.replace("`", "");
            let (def, fragment) = {
                let mut kind = PathKind::Unknown;
                let path_str = if let Some(prefix) =
                    ["struct@", "enum@", "type@",
                     "trait@", "union@"].iter()
                                      .find(|p| link.starts_with(**p)) {
                    kind = PathKind::Type;
                    link.trim_start_matches(prefix)
                } else if let Some(prefix) =
                    ["const@", "static@",
                     "value@", "function@", "mod@",
                     "fn@", "module@", "method@"]
                        .iter().find(|p| link.starts_with(**p)) {
                    kind = PathKind::Value;
                    link.trim_start_matches(prefix)
                } else if link.ends_with("()") {
                    kind = PathKind::Value;
                    link.trim_end_matches("()")
                } else if link.starts_with("macro@") {
                    kind = PathKind::Macro;
                    link.trim_start_matches("macro@")
                } else if link.ends_with('!') {
                    kind = PathKind::Macro;
                    link.trim_end_matches('!')
                } else {
                    &link[..]
                }.trim();

                if path_str.contains(|ch: char| !(ch.is_alphanumeric() ||
                                                  ch == ':' || ch == '_')) {
                    continue;
                }

                match kind {
                    PathKind::Value => {
                        if let Ok(def) = self.resolve(path_str, true, &current_item, parent_node) {
                            def
                        } else {
                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
                            // This could just be a normal link or a broken link
                            // we could potentially check if something is
                            // "intra-doc-link-like" and warn in that case.
                            continue;
                        }
                    }
                    PathKind::Type => {
                        if let Ok(def) = self.resolve(path_str, false, &current_item, parent_node) {
                            def
                        } else {
                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
                            // This could just be a normal link.
                            continue;
                        }
                    }
                    PathKind::Unknown => {
                        // Try everything!
                        if let Some(macro_def) = macro_resolve(cx, path_str) {
                            if let Ok(type_def) =
                                self.resolve(path_str, false, &current_item, parent_node)
                            {
                                let (type_kind, article, type_disambig)
                                    = type_ns_kind(type_def.0, path_str);
                                ambiguity_error(cx, &item.attrs, path_str,
                                                article, type_kind, &type_disambig,
                                                "a", "macro", &format!("macro@{}", path_str));
                                continue;
                            } else if let Ok(value_def) =
                                self.resolve(path_str, true, &current_item, parent_node)
                            {
                                let (value_kind, value_disambig)
                                    = value_ns_kind(value_def.0, path_str)
                                        .expect("struct and mod cases should have been \
                                                 caught in previous branch");
                                ambiguity_error(cx, &item.attrs, path_str,
                                                "a", value_kind, &value_disambig,
                                                "a", "macro", &format!("macro@{}", path_str));
                            }
                            (macro_def, None)
                        } else if let Ok(type_def) =
                            self.resolve(path_str, false, &current_item, parent_node)
                        {
                            // It is imperative we search for not-a-value first
                            // Otherwise we will find struct ctors for when we are looking
                            // for structs, and the link won't work if there is something in
                            // both namespaces.
                            if let Ok(value_def) =
                                self.resolve(path_str, true, &current_item, parent_node)
                            {
                                let kind = value_ns_kind(value_def.0, path_str);
                                if let Some((value_kind, value_disambig)) = kind {
                                    let (type_kind, article, type_disambig)
                                        = type_ns_kind(type_def.0, path_str);
                                    ambiguity_error(cx, &item.attrs, path_str,
                                                    article, type_kind, &type_disambig,
                                                    "a", value_kind, &value_disambig);
                                    continue;
                                }
                            }
                            type_def
                        } else if let Ok(value_def) =
                            self.resolve(path_str, true, &current_item, parent_node)
                        {
                            value_def
                        } else {
                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
                            // this could just be a normal link
                            continue;
                        }
                    }
                    PathKind::Macro => {
                        if let Some(def) = macro_resolve(cx, path_str) {
                            (def, None)
                        } else {
                            resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
                            continue
                        }
                    }
                }
            };

            if let Def::PrimTy(_) = def {
                item.attrs.links.push((ori_link, None, fragment));
            } else {
                let id = register_def(cx, def);
                item.attrs.links.push((ori_link, Some(id), fragment));
            }
        }

        if item.is_mod() && !item.attrs.inner_docs {
            self.mod_ids.push(item_node_id.unwrap());
        }

        if item.is_mod() {
            let ret = self.fold_item_recur(item);

            self.mod_ids.pop();

            ret
        } else {
            self.fold_item_recur(item)
        }
    }
}

/// Resolve a string as a macro.
fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
    use syntax::ext::base::{MacroKind, SyntaxExtension};
    let segment = ast::PathSegment::from_ident(Ident::from_str(path_str));
    let path = ast::Path { segments: vec![segment], span: DUMMY_SP };
    let mut resolver = cx.resolver.borrow_mut();
    let parent_scope = resolver.dummy_parent_scope();
    if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang,
                                                         &parent_scope, false, false) {
        if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
            return Some(def);
        }
    }
    if let Some(def) = resolver.all_macros.get(&Symbol::intern(path_str)) {
        return Some(*def);
    }
    None
}

/// Reports a resolution failure diagnostic.
///
/// If we cannot find the exact source span of the resolution failure, we use the span of the
/// documentation attributes themselves. This is a little heavy-handed, so we display the markdown
/// line containing the failure as a note as well.
fn resolution_failure(
    cx: &DocContext,
    attrs: &Attributes,
    path_str: &str,
    dox: &str,
    link_range: Option<Range<usize>>,
) {
    let sp = span_of_attrs(attrs);
    let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str);

    let mut diag = if let Some(link_range) = link_range {
        if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs) {
            let mut diag = cx.tcx.struct_span_lint_node(
                lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
                NodeId::from_u32(0),
                sp,
                &msg,
            );
            diag.span_label(sp, "cannot be resolved, ignoring");
            diag
        } else {
            let mut diag = cx.tcx.struct_span_lint_node(
                lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
                NodeId::from_u32(0),
                sp,
                &msg,
            );

            // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
            //                       ^     ~~~~
            //                       |     link_range
            //                       last_new_line_offset
            let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
            let line = dox[last_new_line_offset..].lines().next().unwrap_or("");

            // Print the line containing the `link_range` and manually mark it with '^'s.
            diag.note(&format!(
                "the link appears in this line:\n\n{line}\n\
                 {indicator: <before$}{indicator:^<found$}",
                line=line,
                indicator="",
                before=link_range.start - last_new_line_offset,
                found=link_range.len(),
            ));
            diag
        }
    } else {
        cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
                                     NodeId::from_u32(0),
                                     sp,
                                     &msg)
    };
    diag.help("to escape `[` and `]` characters, just add '\\' before them like \
               `\\[` or `\\]`");
    diag.emit();
}

fn ambiguity_error(cx: &DocContext, attrs: &Attributes,
                   path_str: &str,
                   article1: &str, kind1: &str, disambig1: &str,
                   article2: &str, kind2: &str, disambig2: &str) {
    let sp = span_of_attrs(attrs);
    cx.sess()
      .struct_span_warn(sp,
                        &format!("`{}` is both {} {} and {} {}",
                                 path_str, article1, kind1,
                                 article2, kind2))
      .help(&format!("try `{}` if you want to select the {}, \
                      or `{}` if you want to \
                      select the {}",
                      disambig1, kind1, disambig2,
                      kind2))
      .emit();
}

/// Given a def, returns its name and disambiguator
/// for a value namespace.
///
/// Returns `None` for things which cannot be ambiguous since
/// they exist in both namespaces (structs and modules).
fn value_ns_kind(def: Def, path_str: &str) -> Option<(&'static str, String)> {
    match def {
        // Structs, variants, and mods exist in both namespaces; skip them.
        Def::StructCtor(..) | Def::Mod(..) | Def::Variant(..) |
        Def::VariantCtor(..) | Def::SelfCtor(..)
            => None,
        Def::Fn(..)
            => Some(("function", format!("{}()", path_str))),
        Def::Method(..)
            => Some(("method", format!("{}()", path_str))),
        Def::Const(..)
            => Some(("const", format!("const@{}", path_str))),
        Def::Static(..)
            => Some(("static", format!("static@{}", path_str))),
        _ => Some(("value", format!("value@{}", path_str))),
    }
}

/// Given a def, returns its name, the article to be used, and a disambiguator
/// for the type namespace.
fn type_ns_kind(def: Def, path_str: &str) -> (&'static str, &'static str, String) {
    let (kind, article) = match def {
        // We can still have non-tuple structs.
        Def::Struct(..) => ("struct", "a"),
        Def::Enum(..) => ("enum", "an"),
        Def::Trait(..) => ("trait", "a"),
        Def::Union(..) => ("union", "a"),
        _ => ("type", "a"),
    };
    (kind, article, format!("{}@{}", kind, path_str))
}

/// Given an enum variant's def, return the def of its enum and the associated fragment.
fn handle_variant(cx: &DocContext, def: Def) -> Result<(Def, Option<String>), ()> {
    use rustc::ty::DefIdTree;

    let parent = if let Some(parent) = cx.tcx.parent(def.def_id()) {
        parent
    } else {
        return Err(())
    };
    let parent_def = Def::Enum(parent);
    let variant = cx.tcx.expect_variant_def(def);
    Ok((parent_def, Some(format!("{}.v", variant.ident.name))))
}

const PRIMITIVES: &[(&str, Def)] = &[
    ("u8",    Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U8))),
    ("u16",   Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U16))),
    ("u32",   Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U32))),
    ("u64",   Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U64))),
    ("u128",  Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U128))),
    ("usize", Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::Usize))),
    ("i8",    Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I8))),
    ("i16",   Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I16))),
    ("i32",   Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I32))),
    ("i64",   Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I64))),
    ("i128",  Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I128))),
    ("isize", Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::Isize))),
    ("f32",   Def::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F32))),
    ("f64",   Def::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F64))),
    ("str",   Def::PrimTy(hir::PrimTy::Str)),
    ("bool",  Def::PrimTy(hir::PrimTy::Bool)),
    ("char",  Def::PrimTy(hir::PrimTy::Char)),
];

fn is_primitive(path_str: &str, is_val: bool) -> Option<Def> {
    if is_val {
        None
    } else {
        PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1)
    }
}
