/*
 * [The "BSD licence"]
 * Copyright (c) 2010 Ben Gruver
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import org.antlr.runtime.ANTLRInputStream;
import org.antlr.runtime.CommonToken;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.jf.smali.expectedTokensTestGrammarLexer;
import org.jf.smali.expectedTokensTestGrammarParser;
import org.jf.smali.smaliFlexLexer;
import org.jf.smali.smaliParser;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;

import static org.jf.smali.expectedTokensTestGrammarParser.ExpectedToken;

public class LexerTest {
    private static final HashMap<String, Integer> tokenTypesByName;

    static {
        tokenTypesByName = new HashMap<String, Integer>();

        for (int i=0; i<smaliParser.tokenNames.length; i++) {
            tokenTypesByName.put(smaliParser.tokenNames[i], i);
        }
    }

    @Test
    public void DirectiveTest() {
        runTest("DirectiveTest");
    }

    @Test
    public void ByteLiteralTest() {
        runTest("ByteLiteralTest");
    }

    @Test
    public void ShortLiteralTest() {
        runTest("ShortLiteralTest");
    }

    @Test
    public void IntegerLiteralTest() {
        runTest("IntegerLiteralTest");
    }

    @Test
    public void LongLiteralTest() {
        runTest("LongLiteralTest");
    }

    @Test
    public void FloatLiteralTest() {
        runTest("FloatLiteralTest");
    }

    @Test
    public void CharLiteralTest() {
        runTest("CharLiteralTest");
    }

    @Test
    public void StringLiteralTest() {
        runTest("StringLiteralTest");
    }

    @Test
    public void MiscTest() {
        runTest("MiscTest");
    }

    @Test
    public void CommentTest() {
        runTest("CommentTest", false);
    }

    @Test
    public void InstructionTest() {
        runTest("InstructionTest", true);
    }

    @Test
    public void TypeAndIdentifierTest() {
        runTest("TypeAndIdentifierTest");
    }

    @Test
    public void SymbolTest() {
        runTest("SymbolTest", false);
    }

    @Test
    public void RealSmaliFileTest() {
        runTest("RealSmaliFileTest", true);
    }

    public void runTest(String test) {
        runTest(test, true);
    }

    public void runTest(String test, boolean discardHiddenTokens) {
        String smaliFile = String.format("LexerTest%s%s.smali", File.separatorChar, test);
        String tokensFile = String.format("LexerTest%s%s.tokens", File.separatorChar, test);

        expectedTokensTestGrammarLexer expectedTokensLexer = null;
        try {
            expectedTokensLexer = new expectedTokensTestGrammarLexer(new ANTLRInputStream(
                    LexerTest.class.getClassLoader().getResourceAsStream(tokensFile)));
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }

        CommonTokenStream expectedTokensStream = new CommonTokenStream(expectedTokensLexer);

        expectedTokensTestGrammarParser expectedTokensParser =
                new expectedTokensTestGrammarParser(expectedTokensStream);
        try {
            expectedTokensParser.top();
        } catch (RecognitionException ex) {
            throw new RuntimeException(ex);
        }

        List<ExpectedToken> expectedTokens = expectedTokensParser.getExpectedTokens();

        InputStream smaliStream = LexerTest.class.getClassLoader().getResourceAsStream(smaliFile);
        if (smaliStream == null) {
            Assert.fail("Could not load " + smaliFile);
        }
        smaliFlexLexer lexer = new smaliFlexLexer(new InputStreamReader(smaliStream));
        lexer.setSourceFile(new File(test + ".smali"));
        lexer.setSuppressErrors(true);

        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
        tokenStream.fill();
        List tokens = tokenStream.getTokens();

        int expectedTokenIndex = 0;
        CommonToken token;
        for (int i=0; i<tokens.size()-1; i++) {
            token = (CommonToken)tokens.get(i);

            if (discardHiddenTokens && token.getChannel() == smaliParser.HIDDEN) {
                continue;
            }

            if (expectedTokenIndex >= expectedTokens.size()) {
                Assert.fail("Too many tokens");
            }

            if (token.getType() == smaliParser.INVALID_TOKEN) {
                Assert.assertTrue("Encountered an INVALID_TOKEN not on the error channel",
                        token.getChannel() == smaliParser.ERROR_CHANNEL);
            }

            ExpectedToken expectedToken = expectedTokens.get(expectedTokenIndex++);
            if (!tokenTypesByName.containsKey(expectedToken.tokenName)) {
                Assert.fail("Unknown token: " + expectedToken.tokenName);
            }
            int expectedTokenType = tokenTypesByName.get(expectedToken.tokenName);

            if (token.getType() != expectedTokenType) {
                Assert.fail(String.format("Invalid token at index %d. Expecting %s, got %s(%s)",
                        expectedTokenIndex-1, expectedToken.tokenName, getTokenName(token.getType()), token.getText()));
            }

            if (expectedToken.tokenText != null) {
                if (!expectedToken.tokenText.equals(token.getText())) {
                    Assert.fail(
                            String.format("Invalid token text at index %d. Expecting text \"%s\", got \"%s\"",
                                    expectedTokenIndex - 1, expectedToken.tokenText, token.getText()));
                }
            }
        }

        if (expectedTokenIndex < expectedTokens.size()) {
            Assert.fail(String.format("Not enough tokens. Expecting %d tokens, but got %d", expectedTokens.size(),
                    expectedTokenIndex));
        }
    }



    private static String getTokenName(int tokenType) {
        return smaliParser.tokenNames[tokenType];
    }
}
