#!/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.
#**/

# Test column expressions with LIKE, BETWEEN and IN operators.

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_LIKE_FILE="${PKG_DIR}/Scripts/TestLike.txt"
INPUT_BETWEEN_FILE="${PKG_DIR}/Scripts/TestBetweenAndIn.txt"
OUTPUT_FILE="${PKG_DIR}/Tests/SwiftKueryTests/TestSpecialOperators.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/testSpecialOperators.sh.
class TestSpecialOperators: XCTestCase {

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

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

        let tableName = "table"
    }

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

EOF

while read -r LINE; do
    [ -z "$LINE" ] && continue
    [[ "$LINE" =~ ^#.*$ ]] && continue
    stringarray=($LINE)
    CLAUSE_TYPE=${stringarray[0]}
    OPERAND=${stringarray[1]}
    SQL_OPERAND=${stringarray[2]}
    ARGUMENT=${stringarray[3]}
    SQL_ARGUMENT=${stringarray[4]}
    SQL_ARGUMENT=${SQL_ARGUMENT/\\}
    CLAUSE_TYPE_UPPER="$(tr '[:lower:]' '[:upper:]' <<< $CLAUSE_TYPE)"
    # Remove backslashes and replace underscores with whitespaces.
    OPERAND=${OPERAND/\\}
    SQL_OPERAND=${SQL_OPERAND/\\}
    SQL_ARGUMENT=${SQL_ARGUMENT/\\}
    OPERAND=${OPERAND//_/" "}
    ARGUMENT=${ARGUMENT//_/" "}
    SQL_OPERAND=${SQL_OPERAND//_/" "}
    SQL_ARGUMENT=${SQL_ARGUMENT//_/" "}

cat <<EOF >> ${OUTPUT_FILE}
        s = Select(t.a, from: t)
            .group(by: t.a)
            .$CLAUSE_TYPE($OPERAND.notLike($ARGUMENT))
        kuery = connection.descriptionOf(query: s)
        queryWhere = "SELECT table.a FROM table $CLAUSE_TYPE_UPPER $SQL_OPERAND NOT LIKE $SQL_ARGUMENT GROUP BY table.a"
        queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_TYPE_UPPER $SQL_OPERAND NOT LIKE $SQL_ARGUMENT"
        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_TYPE($OPERAND.like($ARGUMENT))
        kuery = connection.descriptionOf(query: s)
        queryWhere = "SELECT table.a FROM table $CLAUSE_TYPE_UPPER $SQL_OPERAND LIKE $SQL_ARGUMENT GROUP BY table.a"
        queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_TYPE_UPPER $SQL_OPERAND LIKE $SQL_ARGUMENT"
        XCTAssert(kuery == queryWhere || kuery == queryHaving,
                    "\nError in query construction: \n\(kuery) \ninstead of \n\(queryWhere) \nor instead of \n\(queryHaving)")
EOF
done < $INPUT_LIKE_FILE

while read -r LINE; do
    [ -z "$LINE" ] && continue
    [[ "$LINE" =~ ^#.*$ ]] && continue
    stringarray=($LINE)
    CLAUSE_TYPE=${stringarray[0]}
    OPERAND=${stringarray[1]}
    SQL_OPERAND=${stringarray[2]}
    ARGUMENT1=${stringarray[3]}
    ARGUMENT2=${stringarray[4]}
    SQL_ARGUMENT1=${stringarray[5]}
    SQL_ARGUMENT1=${SQL_ARGUMENT1/\\}
    SQL_ARGUMENT2=${stringarray[6]}
    SQL_ARGUMENT2=${SQL_ARGUMENT2/\\}
    CLAUSE_TYPE_UPPER="$(tr '[:lower:]' '[:upper:]' <<< $CLAUSE_TYPE)"
    # Remove backslashes and replace underscores with whitespaces.
    SQL_OPERAND=${SQL_OPERAND/\\}
    SQL_ARGUMENT1=${SQL_ARGUMENT1/\\}
    SQL_ARGUMENT2=${SQL_ARGUMENT2/\\}
    SQL_OPERAND=${SQL_OPERAND//_/" "}
    OPERAND=${OPERAND//_/" "}
    ARGUMENT1=${ARGUMENT1//_/" "}
    ARGUMENT2=${ARGUMENT2//_/" "}
    SQL_ARGUMENT1=${SQL_ARGUMENT1//_/" "}
    SQL_ARGUMENT2=${SQL_ARGUMENT2//_/" "}

cat <<EOF >> ${OUTPUT_FILE}

        s = Select(t.a, from: t)
            .group(by: t.a)
            .$CLAUSE_TYPE($OPERAND.between($ARGUMENT1, and: $ARGUMENT2))
        kuery = connection.descriptionOf(query: s)
        queryWhere = "SELECT table.a FROM table $CLAUSE_TYPE_UPPER $SQL_OPERAND BETWEEN $SQL_ARGUMENT1 AND $SQL_ARGUMENT2 GROUP BY table.a"
        queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_TYPE_UPPER $SQL_OPERAND BETWEEN $SQL_ARGUMENT1 AND $SQL_ARGUMENT2"
        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_TYPE($OPERAND.notBetween($ARGUMENT1, and: $ARGUMENT2))
        kuery = connection.descriptionOf(query: s)
        queryWhere = "SELECT table.a FROM table $CLAUSE_TYPE_UPPER $SQL_OPERAND NOT BETWEEN $SQL_ARGUMENT1 AND $SQL_ARGUMENT2 GROUP BY table.a"
        queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_TYPE_UPPER $SQL_OPERAND NOT BETWEEN $SQL_ARGUMENT1 AND $SQL_ARGUMENT2"
        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_TYPE($OPERAND.in($ARGUMENT1, $ARGUMENT2))
        kuery = connection.descriptionOf(query: s)
        queryWhere = "SELECT table.a FROM table $CLAUSE_TYPE_UPPER $SQL_OPERAND IN ($SQL_ARGUMENT1, $SQL_ARGUMENT2) GROUP BY table.a"
        queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_TYPE_UPPER $SQL_OPERAND IN ($SQL_ARGUMENT1, $SQL_ARGUMENT2)"
        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_TYPE($OPERAND.notIn($ARGUMENT1, $ARGUMENT2))
        kuery = connection.descriptionOf(query: s)
        queryWhere = "SELECT table.a FROM table $CLAUSE_TYPE_UPPER $SQL_OPERAND NOT IN ($SQL_ARGUMENT1, $SQL_ARGUMENT2) GROUP BY table.a"
        queryHaving = "SELECT table.a FROM table GROUP BY table.a $CLAUSE_TYPE_UPPER $SQL_OPERAND NOT IN ($SQL_ARGUMENT1, $SQL_ARGUMENT2)"
        XCTAssert(kuery == queryWhere || kuery == queryHaving,
                    "\nError in query construction: \n\(kuery) \ninstead of \n\(queryWhere) \nor instead of \n\(queryHaving)")
EOF
done < $INPUT_BETWEEN_FILE

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