package com.novoda.sqlite.impl;

import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

public class SQLFileTest {
    private final static String STATEMENT_CREATE_TABLE = "CREATE TABLE banana(_id INTEGER);";
    private final static String STATEMENT_ALTER_TABLE = "ALTER TABLE banana ADD COLUMN colour TEXT;";
    private final static String NEW_LINE = "\n";
    private final static String SPACE = " ";
    private final static String[] EXPECTED_STATEMENTS = new String[]{STATEMENT_CREATE_TABLE, STATEMENT_ALTER_TABLE};
    private final static String LINE_COMMENT = "-- this is a line comment";
    private static final String BLOCK_COMMENT = "/* this is a \n block comment \n spanning over \n multiple lines */";
    private final static String STATEMENT_FOR_COMMENTS_WITHIN_TESTS_1 = "CREATE TABLE";
    private final static String STATEMENT_FOR_COMMENTS_WITHIN_TESTS_2 = "banana(_id INTEGER);";

    @Test
    public void givenSQLFile_whenParseAndGetStatements_thenGetCorrectStatements() throws IOException {
        SQLFile file = givenSQLFileParsedFromString(STATEMENT_CREATE_TABLE + NEW_LINE + STATEMENT_ALTER_TABLE);

        String[] actual = getStatementsFromFile(file);

        assertArrayEquals(actual, EXPECTED_STATEMENTS);
    }

    @Test
    public void givenSQLFileWithSpaces_whenParseAndGetStatements_thenGetCorrectTrimmedStatements() throws IOException {
        SQLFile file = givenSQLFileParsedFromString(SPACE + STATEMENT_CREATE_TABLE + SPACE + NEW_LINE + SPACE + STATEMENT_ALTER_TABLE + SPACE);

        String[] actual = getStatementsFromFile(file);

        assertArrayEquals(actual, EXPECTED_STATEMENTS);
    }

    @Test
    public void givenSQLFileWithLineComments_whenParseAndGetStatements_thenIgnoreComments() throws IOException {
        SQLFile file = givenSQLFileParsedFromString(
                STATEMENT_CREATE_TABLE + SPACE + LINE_COMMENT + NEW_LINE + STATEMENT_ALTER_TABLE + SPACE + LINE_COMMENT
        );

        String[] actual = getStatementsFromFile(file);

        assertArrayEquals(actual, EXPECTED_STATEMENTS);
    }

    @Test
    public void givenSQLFileWithBlockComments_whenParseAndGetStatements_thenIgnoreComments() throws IOException {
        SQLFile file = givenSQLFileParsedFromString(
                STATEMENT_CREATE_TABLE + NEW_LINE + BLOCK_COMMENT + NEW_LINE + STATEMENT_ALTER_TABLE
        );

        String[] actual = getStatementsFromFile(file);

        assertArrayEquals(actual, EXPECTED_STATEMENTS);
    }

    @Test
    public void givenSQLFileWithLineCommentsWithinStatement_whenParseAndGetStatements_thenIgnoreComments() throws IOException {
        SQLFile file = givenSQLFileParsedFromString(
                STATEMENT_FOR_COMMENTS_WITHIN_TESTS_1 + NEW_LINE + LINE_COMMENT + NEW_LINE + STATEMENT_FOR_COMMENTS_WITHIN_TESTS_2
        );

        String[] actual = getStatementsFromFile(file);

        assertEquals(actual.length, 1);
        assertEquals(actual[0], STATEMENT_FOR_COMMENTS_WITHIN_TESTS_1 + SPACE + STATEMENT_FOR_COMMENTS_WITHIN_TESTS_2);
    }

    @Test
    public void givenSQLFileWithBlockCommentsWithinStatement_whenParseAndGetStatements_thenIgnoreComments() throws IOException {
        SQLFile file = givenSQLFileParsedFromString(
                STATEMENT_FOR_COMMENTS_WITHIN_TESTS_1 + NEW_LINE + BLOCK_COMMENT + NEW_LINE + STATEMENT_FOR_COMMENTS_WITHIN_TESTS_2
        );

        String[] actual = getStatementsFromFile(file);

        assertEquals(actual.length, 1);
        assertEquals(actual[0], STATEMENT_FOR_COMMENTS_WITHIN_TESTS_1 + SPACE + STATEMENT_FOR_COMMENTS_WITHIN_TESTS_2);
    }

    private SQLFile givenSQLFileParsedFromString(String sql) throws IOException {
        SQLFile sqlFile = new SQLFile();
        sqlFile.parse(new StringReader(sql));
        return sqlFile;
    }

    private String[] getStatementsFromFile(SQLFile file) {
        List<String> statements = file.getStatements();
        return statements.toArray(new String[statements.size()]);
    }
}

@@ -1089,32 +1089,16 @@
 henParse
-AndGetStatements
 _thenGet
@@ -1173,33 +1173,50 @@
 nSQLFile
+When
 Parse
-dFrom
+(
 String
-(
+.format(%22%25s%5Cn%25s%22, 
 STATEMEN
@@ -1229,29 +1229,17 @@
 TE_TABLE
- + NEW_LINE +
+,
  STATEME
@@ -1253,16 +1253,17 @@
 R_TABLE)
+)
 ;%0A%0A     
@@ -1304,33 +1304,32 @@
 FromFile(file);%0A
-%0A
         assertAr
@@ -1433,32 +1433,16 @@
 henParse
-AndGetStatements
 _thenGet
@@ -1524,32 +1524,25 @@
 nSQLFile
+When
 Parse
-dFromString
 (SPACE +
@@ -1674,33 +1674,32 @@
 FromFile(file);%0A
-%0A
         assertAr
@@ -1809,32 +1809,16 @@
 henParse
-AndGetStatements
 _thenIgn
@@ -1887,32 +1887,25 @@
 nSQLFile
+When
 Parse
-dFromString
 (%0A      
@@ -2077,33 +2077,32 @@
 FromFile(file);%0A
-%0A
         assertAr
@@ -2213,32 +2213,16 @@
 henParse
-AndGetStatements
 _thenIgn
@@ -2291,32 +2291,25 @@
 nSQLFile
+When
 Parse
-dFromString
 (%0A      
@@ -2462,33 +2462,32 @@
 FromFile(file);%0A
-%0A
         assertAr
@@ -2612,32 +2612,16 @@
 henParse
-AndGetStatements
 _thenIgn
@@ -2690,32 +2690,25 @@
 nSQLFile
+When
 Parse
-dFromString
 (%0A      
@@ -2891,33 +2891,32 @@
 FromFile(file);%0A
-%0A
         assertEq
@@ -3150,24 +3150,8 @@
 arse
-AndGetStatements
 _the
@@ -3224,32 +3224,25 @@
 nSQLFile
+When
 Parse
-dFromString
 (%0A      
@@ -3434,17 +3434,16 @@
 (file);%0A
-%0A
         
@@ -3637,24 +3637,17 @@
 File
+When
 Parse
-dFromString
 (Str

Rename test methods and `given...When` builder