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

    let sp = cx.with_legacy_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
    }
}
