#!/bin/bash

#/**
#* Copyright IBM Corporation 2016, 2017
#*
#* Licensed under the Apache License, Version 2.0 (the "License");
#* you may not use this file except in compliance with the License.
#* You may obtain a copy of the License at
#*
#* http://www.apache.org/licenses/LICENSE-2.0
#*
#* Unless required by applicable law or agreed to in writing, software
#* distributed under the License is distributed on an "AS IS" BASIS,
#* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#* See the License for the specific language governing permissions and
#* limitations under the License.
#**/

SCRIPT_DIR=$(dirname "$BASH_SOURCE")
cd "$SCRIPT_DIR"
CUR_DIR=$(pwd)

temp=$(dirname "${CUR_DIR}")
temp=$(dirname "${temp}")
PKG_DIR=$(dirname "${CUR_DIR}")

shopt -s nullglob

if ! [ -d "${PKG_DIR}/Tests/SwiftKueryTests" ]; then
echo "Failed to find ${PKG_DIR}/Tests/SwiftKueryTests"
exit 1
fi

INPUT_OPERATORS_FILE="${PKG_DIR}/Scripts/SimpleOperators.txt"
INPUT_TYPES_FILE="${PKG_DIR}/Scripts/SubqueriesTypes.txt"
INPUT_IN_SUBQUERY_TYPES_FILE="${PKG_DIR}/Scripts/InSelectTypes.txt"

OUTPUT_FILE="${PKG_DIR}/Tests/SwiftKueryTests/TestSubqueries.swift"

echo "--- Generating ${OUTPUT_FILE}"

cat <<'EOF' > ${OUTPUT_FILE}
/**
* Copyright IBM Corporation 2016, 2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

import Foundation

import XCTest

@testable import SwiftKuery

// This test was generated by Scripts/testSubqueries.sh.
class TestSubqueries: XCTestCase {

    static var allTests: [(String, (TestSubqueries) -> () throws -> Void)] {
        return [
            ("testSubqueries", testSubqueries),
        ]
    }

    class MyTable: Table {
        let a = Column("a")
        let b = Column("b")

        let tableName = "table"
    }

    class MyTable2: Table {
        let c = Column("c")
        let tableName = "table2"
    }

    func testSubqueries() {
        let t = MyTable()
        let t2 = MyTable2()
        let connection = createConnection()
        var s = Select(from: t)
        var kuery = ""
        var queryWhere = ""
        var queryHaving = ""

EOF


# Generate test for operators with subqueries, i.e. 'expression operator ANY/ALL(subquery)'
while read -r LINE; do
    [ -z "$LINE" ] && continue
    [[ "$LINE" =~ ^#.*$ ]] && continue
    stringarray=($LINE)
    OPERATOR=${stringarray[0]}
    SQL_OPERATOR=${stringarray[2]}
    while read -r LINE; do
        [ -z "$LINE" ] && continue
        [[ "$LINE" =~ ^#.*$ ]] && continue
        stringarray=($LINE)
        CLAUSE=${stringarray[3]}
        OPERAND1=${stringarray[4]}
        OPERAND2=${stringarray[5]}
        SQL_OPERAND1=${stringarray[6]}
        SQL_OPERAND2=${stringarray[7]}

        CLAUSE_UPPER="$(tr '[:lower:]' '[:upper:]' <<< $CLAUSE)"
        # Remove backslashes.
        SQL_OPERAND1=${SQL_OPERAND1/\\}
        SQL_OPERAND2=${SQL_OPERAND2/\\}
        # Replace underscores with whitespaces.
        OPERAND1=${OPERAND1//_/" "}
        OPERAND2=${OPERAND2//_/" "}
        SQL_OPERAND1=${SQL_OPERAND1//_/" "}
        SQL_OPERAND2=${SQL_OPERAND2//_/" "}

cat <<EOF >> ${OUTPUT_FILE}

        s = Select(t.a, from: t)
            .group(by: t.a)
            .$CLAUSE($OPERAND1 $OPERATOR $OPERAND2)
        kuery = connection.descriptionOf(query: s)
        queryWhere = "SELECT table.a FROM table $CLAUSE_UPPER $SQL_OPERAND1 $SQL_OPERATOR $SQL_OPERAND2 GROUP BY table.a"
        queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_UPPER $SQL_OPERAND1 $SQL_OPERATOR $SQL_OPERAND2"
        XCTAssert(kuery == queryWhere || kuery == queryHaving,
                    "\nError in query construction: \n\(kuery) \ninstead of \n\(queryWhere) \nor instead of \n\(queryHaving)")
EOF

    done < $INPUT_TYPES_FILE
done < $INPUT_OPERATORS_FILE


# Generate tests extensions for IN, NOT IN with subquery
while read -r LINE; do
    [ -z "$LINE" ] && continue
    [[ "$LINE" =~ ^#.*$ ]] && continue
    stringarray=($LINE)
    CLAUSE=${stringarray[2]}
    OPERAND1=${stringarray[3]}
    SQL_OPERAND1=${stringarray[4]}

    CLAUSE_UPPER="$(tr '[:lower:]' '[:upper:]' <<< $CLAUSE)"
    # Remove backslashes and whitespaces.
    SQL_OPERAND1=${SQL_OPERAND1/\\}
    OPERAND1=${OPERAND1//_/" "}
    SQL_OPERAND1=${SQL_OPERAND1//_/" "}

cat <<EOF >> ${OUTPUT_FILE}

    s = Select(t.a, from: t)
        .group(by: t.a)
        .$CLAUSE($OPERAND1.in(Select(t2.c, from: t2)))
    kuery = connection.descriptionOf(query: s)
    queryWhere = "SELECT table.a FROM table $CLAUSE_UPPER $SQL_OPERAND1 IN (SELECT table2.c FROM table2) GROUP BY table.a"
    queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_UPPER $SQL_OPERAND1 IN (SELECT table2.c FROM table2)"
    XCTAssert(kuery == queryWhere || kuery == queryHaving,
                "\nError in query construction: \n\(kuery) \ninstead of \n\(queryWhere) \nor instead of \n\(queryHaving)")

    s = Select(t.a, from: t)
        .group(by: t.a)
        .$CLAUSE($OPERAND1.notIn(Select(t2.c, from: t2)))
    kuery = connection.descriptionOf(query: s)
    queryWhere = "SELECT table.a FROM table $CLAUSE_UPPER $SQL_OPERAND1 NOT IN (SELECT table2.c FROM table2) GROUP BY table.a"
    queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_UPPER $SQL_OPERAND1 NOT IN (SELECT table2.c FROM table2)"
    XCTAssert(kuery == queryWhere || kuery == queryHaving,
                    "\nError in query construction: \n\(kuery) \ninstead of \n\(queryWhere) \nor instead of \n\(queryHaving)")
EOF

done < $INPUT_IN_SUBQUERY_TYPES_FILE

echo "  }" >> ${OUTPUT_FILE}
echo "}" >> ${OUTPUT_FILE}
