/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
package org.apache.cassandra.cql3.validation.miscellaneous;

import java.math.BigInteger;

import org.junit.Test;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.utils.ByteBufferUtil;

/**
 * Any tests that do not fit in any other category,
 * migrated from python dtests, CASSANDRA-9160
 **/
public class OverflowTest extends CQLTester
{
    /**
     * Test support for nulls
     * migrated from cql_tests.py:TestCQL.null_support_test()
     */
    @Test
    public void testNullSupport() throws Throwable
    {
        createTable("CREATE TABLE %s (k int, c int, v1 int, v2 set<text>, PRIMARY KEY (k, c))");

        execute("INSERT INTO %s (k, c, v1, v2) VALUES (0, 0, null, {'1', '2'})");
        execute("INSERT INTO %s (k, c, v1) VALUES (0, 1, 1)");

        assertRows(execute("SELECT * FROM %s"),
                   row(0, 0, null, set("1", "2")),
                   row(0, 1, 1, null));

        execute("INSERT INTO %s (k, c, v1) VALUES (0, 1, null)");
        execute("INSERT INTO %s (k, c, v2) VALUES (0, 0, null)");

        assertRows(execute("SELECT * FROM %s"),
                   row(0, 0, null, null),
                   row(0, 1, null, null));

        assertInvalid("INSERT INTO %s (k, c, v2) VALUES (0, 2, {1, null})");
        assertInvalid("SELECT * FROM %s WHERE k = null");
        assertInvalid("INSERT INTO %s (k, c, v2) VALUES (0, 0, { 'foo', 'bar', null })");
    }

    /**
     * Test reserved keywords
     * migrated from cql_tests.py:TestCQL.reserved_keyword_test()
     */
    @Test
    public void testReservedKeywords() throws Throwable
    {
        createTable("CREATE TABLE %s (key text PRIMARY KEY, count counter)");

        String tableName = createTableName();
        assertInvalidThrow(SyntaxException.class, String.format("CREATE TABLE %s.%s (select text PRIMARY KEY, x int)", keyspace(), tableName));
    }

    /**
     * Test identifiers
     * migrated from cql_tests.py:TestCQL.identifier_test()
     */
    @Test
    public void testIdentifiers() throws Throwable
    {
        createTable("CREATE TABLE %s (key_23 int PRIMARY KEY, CoLuMn int)");

        execute("INSERT INTO %s (Key_23, Column) VALUES (0, 0)");
        execute("INSERT INTO %s (KEY_23, COLUMN) VALUES (0, 0)");

        assertInvalid("INSERT INTO %s (key_23, column, column) VALUES (0, 0, 0)");
        assertInvalid("INSERT INTO %s (key_23, column, COLUMN) VALUES (0, 0, 0)");
        assertInvalid("INSERT INTO %s (key_23, key_23, column) VALUES (0, 0, 0)");
        assertInvalid("INSERT INTO %s (key_23, KEY_23, column) VALUES (0, 0, 0)");

        String tableName = createTableName();
        assertInvalidThrow(SyntaxException.class, String.format("CREATE TABLE %s.%s (select int PRIMARY KEY, column int)", keyspace(), tableName));
    }

    /**
     * Test table options
     * migrated from cql_tests.py:TestCQL.table_options_test()
     */
    @Test
    public void testTableOptions() throws Throwable
    {
        createTable("CREATE TABLE %s ( k int PRIMARY KEY, c int ) WITH "
                    + "comment = 'My comment' "
                    + "AND read_repair_chance = 0.5 "
                    + "AND dclocal_read_repair_chance = 0.5 "
                    + "AND gc_grace_seconds = 4 "
                    + "AND bloom_filter_fp_chance = 0.01 "
                    + "AND compaction = { 'class' : 'LeveledCompactionStrategy', 'sstable_size_in_mb' : 10 } "
                    + "AND compression = { 'enabled': false } "
                    + "AND caching = { 'keys': 'ALL', 'rows_per_partition': 'ALL' }");

        execute("ALTER TABLE %s WITH "
                + "comment = 'other comment' "
                + "AND read_repair_chance = 0.3 "
                + "AND dclocal_read_repair_chance = 0.3 "
                + "AND gc_grace_seconds = 100 "
                + "AND bloom_filter_fp_chance = 0.1 "
                + "AND compaction = { 'class': 'SizeTieredCompactionStrategy', 'min_sstable_size' : 42 } "
                + "AND compression = { 'class' : 'SnappyCompressor' } "
                + "AND caching = { 'rows_per_partition': 'ALL' }");
    }

    /**
     * Migrated from cql_tests.py:TestCQL.unescaped_string_test()
     */
    @Test
    public void testUnescapedString() throws Throwable
    {
        createTable("CREATE TABLE %s ( k text PRIMARY KEY, c text, )");

        //The \ in this query string is not forwarded to cassandra.
        //The ' is being escaped in python, but only ' is forwarded
        //over the wire instead of \'.
        assertInvalidThrow(SyntaxException.class, "INSERT INTO %s (k, c) VALUES ('foo', 'CQL is cassandra\'s best friend')");
    }

    /**
     * Migrated from cql_tests.py:TestCQL.boolean_test()
     */
    @Test
    public void testBoolean() throws Throwable
    {
        createTable("CREATE TABLE %s (k boolean PRIMARY KEY, b boolean)");

        execute("INSERT INTO %s (k, b) VALUES (true, false)");
        assertRows(execute("SELECT * FROM %s WHERE k = true"),
                   row(true, false));
    }

    /**
     * Migrated from cql_tests.py:TestCQL.float_with_exponent_test()
     */
    @Test
    public void testFloatWithExponent() throws Throwable
    {
        createTable("CREATE TABLE %s (k int PRIMARY KEY, d double, f float)");

        execute("INSERT INTO %s (k, d, f) VALUES (0, 3E+10, 3.4E3)");
        execute("INSERT INTO %s (k, d, f) VALUES (1, 3.E10, -23.44E-3)");
        execute("INSERT INTO %s (k, d, f) VALUES (2, 3, -2)");
    }

    /**
     * Test regression from #5189,
     * migrated from cql_tests.py:TestCQL.compact_metadata_test()
     */
    @Test
    public void testCompactMetadata() throws Throwable
    {
        createTable("CREATE TABLE %s (id int primary key, i int ) WITH COMPACT STORAGE");

        execute("INSERT INTO %s (id, i) VALUES (1, 2)");
        assertRows(execute("SELECT * FROM %s"),
                   row(1, 2));
    }

    /**
     * Migrated from cql_tests.py:TestCQL.conversion_functions_test()
     */
    @Test
    public void testConversionFunctions() throws Throwable
    {
        createTable("CREATE TABLE %s (k int PRIMARY KEY, i varint, b blob)");

        execute("INSERT INTO %s (k, i, b) VALUES (0, blobAsVarint(bigintAsBlob(3)), textAsBlob('foobar'))");
        assertRows(execute("SELECT i, blobAsText(b) FROM %s WHERE k = 0"),
                   row(BigInteger.valueOf(3), "foobar"));
    }

    /**
     * Migrated from cql_tests.py:TestCQL.empty_blob_test()
     */
    @Test
    public void testEmptyBlob() throws Throwable
    {
        createTable("CREATE TABLE %s (k int PRIMARY KEY, b blob)");
        execute("INSERT INTO %s (k, b) VALUES (0, 0x)");

        assertRows(execute("SELECT * FROM %s"),
                   row(0, ByteBufferUtil.bytes("")));
    }

    private Object[][] fill() throws Throwable
    {
        for (int i = 0; i < 2; i++)
            for (int j = 0; j < 2; j++)
                execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", i, j, i + j);

        return getRows(execute("SELECT * FROM %s"));
    }

    /**
     * Migrated from cql_tests.py:TestCQL.empty_in_test()
     */
    @Test
    public void testEmpty() throws Throwable
    {
        createTable("CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY (k1, k2))");

        // Inserts a few rows to make sure we don 't actually query something
        Object[][] rows = fill();

        // Test empty IN() in SELECT
        assertEmpty(execute("SELECT v FROM %s WHERE k1 IN ()"));
        assertEmpty(execute("SELECT v FROM %s WHERE k1 = 0 AND k2 IN ()"));

        // Test empty IN() in DELETE
        execute("DELETE FROM %s WHERE k1 IN ()");
        assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));

        // Test empty IN() in UPDATE
        execute("UPDATE %s SET v = 3 WHERE k1 IN () AND k2 = 2");
        assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));

        // Same test, but for compact
        createTable("CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY (k1, k2)) WITH COMPACT STORAGE");

        rows = fill();

        assertEmpty(execute("SELECT v FROM %s WHERE k1 IN ()"));
        assertEmpty(execute("SELECT v FROM %s WHERE k1 = 0 AND k2 IN ()"));

        // Test empty IN() in DELETE
        execute("DELETE FROM %s WHERE k1 IN ()");
        assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));

        // Test empty IN() in UPDATE
        execute("UPDATE %s SET v = 3 WHERE k1 IN () AND k2 = 2");
        assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));
    }

    /**
     * Migrated from cql_tests.py:TestCQL.function_with_null_test()
     */
    @Test
    public void testFunctionWithNull() throws Throwable
    {
        createTable("CREATE TABLE %s (k int PRIMARY KEY, t timeuuid,)");

        execute("INSERT INTO %s (k) VALUES (0)");
        Object[][] rows = getRows(execute("SELECT dateOf(t) FROM %s WHERE k=0"));
        assertNull(rows[0][0]);
    }

    /**
     * Migrated from cql_tests.py:TestCQL.column_name_validation_test()
     */
    @Test
    public void testColumnNameValidation() throws Throwable
    {
        createTable("CREATE TABLE %s (k text, c int, v timeuuid, PRIMARY KEY (k, c))");

        assertInvalid("INSERT INTO %s (k, c) VALUES ('', 0)");

        // Insert a value that don't fit 'int'
        assertInvalid("INSERT INTO %s (k, c) VALUES (0, 10000000000)");

        // Insert a non-version 1 uuid
        assertInvalid("INSERT INTO %s (k, c, v) VALUES (0, 0, 550e8400-e29b-41d4-a716-446655440000)");
    }

    /**
     * Migrated from cql_tests.py:TestCQL.nan_infinity_test()
     */
    @Test
    public void testNanInfinityValues() throws Throwable
    {
        createTable("CREATE TABLE %s (f float PRIMARY KEY)");

        execute("INSERT INTO %s (f) VALUES (NaN)");
        execute("INSERT INTO %s (f) VALUES (-NaN)");
        execute("INSERT INTO %s (f) VALUES (Infinity)");
        execute("INSERT INTO %s (f) VALUES (-Infinity)");

        Object[][] selected = getRows(execute("SELECT * FROM %s"));

        // selected should be[[nan],[inf],[-inf]],
        // but assert element - wise because NaN!=NaN
        assertEquals(3, selected.length);
        assertEquals(1, selected[0].length);
        assertTrue(Float.isNaN((Float) selected[0][0]));

        assertTrue(Float.isInfinite((Float) selected[1][0])); //inf
        assertTrue(((Float) selected[1][0]) > 0);

        assertTrue(Float.isInfinite((Float) selected[2][0])); //-inf
        assertTrue(((Float) selected[2][0]) < 0);
    }

    /**
     * Migrated from cql_tests.py:TestCQL.blobAs_functions_test()
     */
    @Test
    public void testBlobAsFunction() throws Throwable
    {
        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");

        //  A blob that is not 4 bytes should be rejected
        assertInvalid("INSERT INTO %s (k, v) VALUES (0, blobAsInt(0x01))");

        execute("INSERT INTO %s (k, v) VALUES (0, blobAsInt(0x00000001))");
        assertRows(execute("select v from %s where k=0"), row(1));
    }
}