/*
 * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
 * license agreements.  See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.  Crate 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.
 *
 * However, if you have executed another commercial license agreement
 * with Crate these terms will supersede the license and you may use the
 * software solely pursuant to the terms of the relevant commercial agreement.
 */

package io.crate.integrationtests;

import io.crate.testing.TestingHelpers;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.hamcrest.core.Is;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.Matchers.is;

public class CustomSchemaIntegrationTest extends SQLTransportIntegrationTest {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void testInformationSchemaTablesReturnCorrectTablesIfCustomSchemaIsSimilarToTableName() throws Exception {
        // regression test.. this caused foobar to be detected as a table in the foo schema and caused a NPE
        execute("create table foobar (id int primary key) with (number_of_replicas = 0)");
        execute("create table foo.bar (id int primary key) with (number_of_replicas = 0)");

        execute("select schema_name, table_name from information_schema.tables " +
                "where table_name like 'foo%' or schema_name = 'foo' order by table_name");
        assertThat(TestingHelpers.printedTable(response.rows()), is("" +
                "foo| bar\n" +
                "doc| foobar\n"));
    }

    @Test
    public void testDeleteFromCustomTable() throws Exception {
        execute("create table custom.t (id int) with (number_of_replicas=0)");
        ensureYellow();
        execute("insert into custom.t (id) values (?)", new Object[][]{{1}, {2}, {3}, {4}});
        refresh();

        execute("select count(*) from custom.t");
        assertThat((Long)response.rows()[0][0], is(4L));

        execute("delete from custom.t where id=1");
        assertThat(response.rowCount(), is(1L));
        refresh();

        execute("select * from custom.t");
        assertThat(response.rowCount(), is(3L));

        execute("delete from custom.t");
        assertThat(response.rowCount(), is(3L));
        refresh();

        execute("select count(*) from custom.t");
        assertThat((Long)response.rows()[0][0], is(0L));
    }

    @Test
    public void testUpdateById() throws Exception {
        execute("create table custom.t (id int, name string) with (number_of_replicas=0)");
        ensureYellow();
        execute("insert into custom.t (id, name) values (?, ?)", new Object[][]{{1, "A"}, {2, "A"}, {3, "A"}, {4, "A"}});
        refresh();

        execute("update custom.t set name='B' where id=1");
        refresh();

        execute("select * from custom.t order by id");
        assertThat(TestingHelpers.printedTable(response.rows()), is("1| B\n2| A\n3| A\n4| A\n"));
    }

    @Test
    public void testGetCustomSchema() throws Exception {
        execute("create table custom.t (id int) with (number_of_replicas=0)");
        ensureYellow();
        execute("insert into custom.t (id) values (?)", new Object[][]{{1}, {2}, {3}, {4}});
        refresh();

        execute("select id from custom.t where id=1");
        assertThat(TestingHelpers.printedTable(response.rows()), is("1\n"));

        execute("select id from custom.t where id in (2,4) order by id");
        assertThat(TestingHelpers.printedTable(response.rows()), is("2\n4\n"));
    }

    @Test
    public void testSelectFromDroppedTableWithMoreThanOneTableInSchema() {
        execute("create table custom.foo (id integer)");
        execute("create table custom.bar (id integer)");
        ensureYellow();

        assertThat(client().admin().indices().exists(new IndicesExistsRequest("custom.foo")).actionGet().isExists(), Is.is(true));
        execute("drop table custom.foo");
        assertThat(client().admin().indices().exists(new IndicesExistsRequest("custom.foo")).actionGet().isExists(), Is.is(false));

        expectedException.expectMessage("Table 'custom.foo' unknown");
        execute("select * from custom.foo");
    }

}

@@ -1190,112 +1190,18 @@
 org.
-hamcrest.core.Is;%0Aimport org.junit.Rule;%0Aimport org.junit.Test;%0Aimport org.junit.rules.ExpectedException
+junit.Test
 ;%0A%0Ai
@@ -1324,94 +1324,8 @@
  %7B%0A%0A
-    @Rule%0A    public ExpectedException expectedException = ExpectedException.none();%0A%0A
     
@@ -4116,16 +4116,33 @@
 Schema()
+ throws Exception
  %7B%0A     
@@ -4392,19 +4392,16 @@
 ists(), 
-Is.
 is(true)
@@ -4566,11 +4566,8 @@
 (), 
-Is.
 is(f
@@ -4587,113 +4587,320 @@
     
-expectedException.expectMessage(%22Table 'custom.foo' unknown%22);%0A        execute(%22select * from custom.foo%22
+assertBusy(new Runnable() %7B%0A            @Override%0A            public void run() %7B%0A                try %7B%0A                    execute(%22select * from custom.foo%22);%0A                    fail(%22should wait for cache invalidation%22);%0A                %7D catch (Exception ignored) %7B%0A                %7D%0A            %7D%0A        %7D
 );%0A 

test should wait for cache invalidation