use errors::{Applicability, DiagnosticBuilder};

use syntax::ast::{self, *};
use syntax::ext::base::*;
use syntax::parse::token::{self, TokenKind};
use syntax::parse::parser::Parser;
use syntax::print::pprust;
use syntax::ptr::P;
use syntax::symbol::{sym, Symbol};
use syntax::tokenstream::{TokenStream, TokenTree};
use syntax_pos::{Span, DUMMY_SP};

pub fn expand_assert<'cx>(
    cx: &'cx mut ExtCtxt<'_>,
    sp: Span,
    tts: TokenStream,
) -> Box<dyn MacResult + 'cx> {
    let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) {
        Ok(assert) => assert,
        Err(mut err) => {
            err.emit();
            return DummyResult::any(sp);
        }
    };

    // `core::panic` and `std::panic` are different macros, so we use call-site
    // context to pick up whichever is currently in scope.
    let sp = cx.with_call_site_ctxt(sp);
    let panic_call = Mac {
        path: Path::from_ident(Ident::new(sym::panic, sp)),
        tts: custom_message.unwrap_or_else(|| {
            TokenStream::from(TokenTree::token(
                TokenKind::lit(token::Str, Symbol::intern(&format!(
                    "assertion failed: {}",
                    pprust::expr_to_string(&cond_expr).escape_debug()
                )), None),
                DUMMY_SP,
            ))
        }).into(),
        delim: MacDelimiter::Parenthesis,
        span: sp,
        prior_type_ascription: None,
    };
    let if_expr = cx.expr_if(
        sp,
        cx.expr(sp, ExprKind::Unary(UnOp::Not, cond_expr)),
        cx.expr(
            sp,
            ExprKind::Mac(panic_call),
        ),
        None,
    );
    MacEager::expr(if_expr)
}

struct Assert {
    cond_expr: P<ast::Expr>,
    custom_message: Option<TokenStream>,
}

fn parse_assert<'a>(
    cx: &mut ExtCtxt<'a>,
    sp: Span,
    stream: TokenStream
) -> Result<Assert, DiagnosticBuilder<'a>> {
    let mut parser = cx.new_parser_from_tts(stream);

    if parser.token == token::Eof {
        let mut err = cx.struct_span_err(sp, "macro requires a boolean expression as an argument");
        err.span_label(sp, "boolean expression required");
        return Err(err);
    }

    let cond_expr = parser.parse_expr()?;

    // Some crates use the `assert!` macro in the following form (note extra semicolon):
    //
    // assert!(
    //     my_function();
    // );
    //
    // Warn about semicolon and suggest removing it. Eventually, this should be turned into an
    // error.
    if parser.token == token::Semi {
        let mut err = cx.struct_span_warn(sp, "macro requires an expression as an argument");
        err.span_suggestion(
            parser.token.span,
            "try removing semicolon",
            String::new(),
            Applicability::MaybeIncorrect
        );
        err.note("this is going to be an error in the future");
        err.emit();

        parser.bump();
    }

    // Some crates use the `assert!` macro in the following form (note missing comma before
    // message):
    //
    // assert!(true "error message");
    //
    // Parse this as an actual message, and suggest inserting a comma. Eventually, this should be
    // turned into an error.
    let custom_message = if let token::Literal(token::Lit { kind: token::Str, .. })
                                = parser.token.kind {
        let mut err = cx.struct_span_warn(parser.token.span, "unexpected string literal");
        let comma_span = cx.source_map().next_point(parser.prev_span);
        err.span_suggestion_short(
            comma_span,
            "try adding a comma",
            ", ".to_string(),
            Applicability::MaybeIncorrect
        );
        err.note("this is going to be an error in the future");
        err.emit();

        parse_custom_message(&mut parser)
    } else if parser.eat(&token::Comma) {
        parse_custom_message(&mut parser)
    } else {
        None
    };

    if parser.token != token::Eof {
        parser.expect_one_of(&[], &[])?;
        unreachable!();
    }

    Ok(Assert { cond_expr, custom_message })
}

fn parse_custom_message(parser: &mut Parser<'_>) -> Option<TokenStream> {
    let ts = parser.parse_tokens();
    if !ts.is_empty() {
        Some(ts)
    } else {
        None
    }
}
