use std::collections::BTreeMap;
use std::env;

use crate::ast::{self, Ident, Name};
use crate::source_map;
use crate::ext::base::{ExtCtxt, MacEager, MacResult};
use crate::parse::token::{self, Token};
use crate::ptr::P;
use crate::symbol::kw;
use crate::tokenstream::{TokenTree};

use smallvec::smallvec;
use syntax_pos::Span;

use crate::diagnostics::metadata::output_metadata;

pub use errors::*;

// Maximum width of any line in an extended error description (inclusive).
const MAX_DESCRIPTION_WIDTH: usize = 80;

/// Error information type.
pub struct ErrorInfo {
    pub description: Option<Name>,
    pub use_site: Option<Span>
}

/// Mapping from error codes to metadata.
pub type ErrorMap = BTreeMap<Name, ErrorInfo>;

pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                   span: Span,
                                   token_tree: &[TokenTree])
                                   -> Box<dyn MacResult+'cx> {
    let code = match token_tree {
        [
            TokenTree::Token(Token { kind: token::Ident(code, _), .. })
        ] => code,
        _ => unreachable!()
    };

    ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
        match diagnostics.get_mut(&code) {
            // Previously used errors.
            Some(&mut ErrorInfo { description: _, use_site: Some(previous_span) }) => {
                ecx.struct_span_warn(span, &format!(
                    "diagnostic code {} already used", code
                )).span_note(previous_span, "previous invocation")
                  .emit();
            }
            // Newly used errors.
            Some(ref mut info) => {
                info.use_site = Some(span);
            }
            // Unregistered errors.
            None => {
                ecx.span_err(span, &format!(
                    "used diagnostic code {} not registered", code
                ));
            }
        }
    });
    MacEager::expr(ecx.expr_tuple(span, Vec::new()))
}

pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                       span: Span,
                                       token_tree: &[TokenTree])
                                       -> Box<dyn MacResult+'cx> {
    let (code, description) = match  token_tree {
        [
            TokenTree::Token(Token { kind: token::Ident(code, _), .. })
        ] => {
            (*code, None)
        },
        [
            TokenTree::Token(Token { kind: token::Ident(code, _), .. }),
            TokenTree::Token(Token { kind: token::Comma, .. }),
            TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..})
        ] => {
            (*code, Some(*symbol))
        },
        _ => unreachable!()
    };

    // Check that the description starts and ends with a newline and doesn't
    // overflow the maximum line width.
    description.map(|raw_msg| {
        let msg = raw_msg.as_str();
        if !msg.starts_with("\n") || !msg.ends_with("\n") {
            ecx.span_err(span, &format!(
                "description for error code {} doesn't start and end with a newline",
                code
            ));
        }

        // URLs can be unavoidably longer than the line limit, so we allow them.
        // Allowed format is: `[name]: https://www.rust-lang.org/`
        let is_url = |l: &str| l.starts_with("[") && l.contains("]:") && l.contains("http");

        if msg.lines().any(|line| line.len() > MAX_DESCRIPTION_WIDTH && !is_url(line)) {
            ecx.span_err(span, &format!(
                "description for error code {} contains a line longer than {} characters.\n\
                 if you're inserting a long URL use the footnote style to bypass this check.",
                code, MAX_DESCRIPTION_WIDTH
            ));
        }
    });
    // Add the error to the map.
    ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
        let info = ErrorInfo {
            description,
            use_site: None
        };
        if diagnostics.insert(code, info).is_some() {
            ecx.span_err(span, &format!(
                "diagnostic code {} already registered", code
            ));
        }
    });

    MacEager::items(smallvec![])
}

pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                          span: Span,
                                          token_tree: &[TokenTree])
                                          -> Box<dyn MacResult+'cx> {
    assert_eq!(token_tree.len(), 3);
    let (crate_name, ident) = match (&token_tree[0], &token_tree[2]) {
        (
            // Crate name.
            &TokenTree::Token(Token { kind: token::Ident(crate_name, _), .. }),
            // DIAGNOSTICS ident.
            &TokenTree::Token(Token { kind: token::Ident(name, _), span })
        ) => (crate_name, Ident::new(name, span)),
        _ => unreachable!()
    };

    // Output error metadata to `tmp/extended-errors/<target arch>/<crate name>.json`
    if let Ok(target_triple) = env::var("CFG_COMPILER_HOST_TRIPLE") {
        ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
            if let Err(e) = output_metadata(ecx,
                                            &target_triple,
                                            &crate_name.as_str(),
                                            diagnostics) {
                ecx.span_bug(span, &format!(
                    "error writing metadata for triple `{}` and crate `{}`, error: {}, \
                     cause: {:?}",
                    target_triple, crate_name, e.description(), e.source()
                ));
            }
        });
    } else {
        ecx.span_err(span, &format!(
            "failed to write metadata for crate `{}` because $CFG_COMPILER_HOST_TRIPLE is not set",
            crate_name));
    }

    // Construct the output expression.
    let (count, expr) =
        ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
            let descriptions: Vec<P<ast::Expr>> =
                diagnostics.iter().filter_map(|(&code, info)| {
                    info.description.map(|description| {
                        ecx.expr_tuple(span, vec![
                            ecx.expr_str(span, code),
                            ecx.expr_str(span, description)
                        ])
                    })
                }).collect();
            (descriptions.len(), ecx.expr_vec(span, descriptions))
        });

    let static_ = ecx.lifetime(span, Ident::with_dummy_span(kw::StaticLifetime));
    let ty_str = ecx.ty_rptr(
        span,
        ecx.ty_ident(span, ecx.ident_of("str")),
        Some(static_),
        ast::Mutability::Immutable,
    );

    let ty = ecx.ty(
        span,
        ast::TyKind::Array(
            ecx.ty(
                span,
                ast::TyKind::Tup(vec![ty_str.clone(), ty_str])
            ),
            ast::AnonConst {
                id: ast::DUMMY_NODE_ID,
                value: ecx.expr_usize(span, count),
            },
        ),
    );

    MacEager::items(smallvec![
        P(ast::Item {
            ident,
            attrs: Vec::new(),
            id: ast::DUMMY_NODE_ID,
            node: ast::ItemKind::Const(
                ty,
                expr,
            ),
            vis: source_map::respan(span.shrink_to_lo(), ast::VisibilityKind::Public),
            span,
            tokens: None,
        })
    ])
}
