/*
 * 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.ignite.internal.runner.app;

import java.util.List;
import org.apache.ignite.app.Ignite;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.table.SchemaMismatchException;
import org.apache.ignite.internal.table.TableImpl;
import org.apache.ignite.schema.SchemaMode;
import org.apache.ignite.table.KeyValueBinaryView;
import org.apache.ignite.table.Table;
import org.apache.ignite.table.Tuple;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * Live schema tests for KV View.
 */
class ITLiveSchemaChangeKVViewTest extends AbstractSchemaChangeTest {
    /**
     * Check exception for unknown column when STRICT_SCHEMA is enabled.
     */
    @Test
    public void testStrictSchemaInsertRowOfNewSchema() {
        List<Ignite> grid = startGrid();

        createTable(grid);

        KeyValueBinaryView view = grid.get(0).tables().table(TABLE).kvView();

        assertThrows(SchemaMismatchException.class, () -> view.put(Tuple.create().set("key", 1L), Tuple.create().set("unknownColumn", 10)));
    }

    /**
     * Check live schema kvBinaryView add columns.
     */
    @Test
    public void testLiveSchemaAddColumns() {
        List<Ignite> grid = startGrid();

        createTable(grid);

        Table tbl = grid.get(1).tables().table(TABLE);

        ((TableImpl)tbl).schemaType(SchemaMode.LIVE_SCHEMA);

        KeyValueBinaryView kvBinaryView = tbl.kvView();

        Tuple key = Tuple.create().set("key", 1L);
        Tuple val = Tuple.create().set("valStrNew", "111").set("valIntNew", 333);

        kvBinaryView.put(key, val);

        Tuple res = kvBinaryView.get(key);
        assertEquals("111", res.value("valStrNew"));
        assertEquals(Integer.valueOf(333), res.value("valIntNew"));
    }

    /**
     * Check strict schema works correctly after live schema
     */
    @Test
    public void testLiveSchemaAddColumnsSwitchToStrict() {
        List<Ignite> grid = startGrid();

        createTable(grid);

        Table tbl = grid.get(0).tables().table(TABLE);

        ((TableImpl)tbl).schemaType(SchemaMode.LIVE_SCHEMA);

        KeyValueBinaryView kvBinaryView = tbl.kvView();

        Tuple key = Tuple.create().set("key", 1L);
        Tuple val = Tuple.create().set("valStrNew", "111").set("valIntNew", 333);

        kvBinaryView.put(key, val);

        Tuple res = kvBinaryView.get(key);
        assertEquals("111", res.value("valStrNew"));
        assertEquals(Integer.valueOf(333), res.value("valIntNew"));

        ((TableImpl)tbl).schemaType(SchemaMode.STRICT_SCHEMA);

        Tuple anotherKey = Tuple.create().set("key", 2L);
        Tuple anotherVal = Tuple.create().set("valStrNew", "111").set("valIntNew", 333);

        kvBinaryView.put(anotherKey, anotherVal);

        Tuple newRes = kvBinaryView.get(anotherKey);

        assertEquals("111", newRes.value("valStrNew"));
        assertEquals(Integer.valueOf(333), newRes.value("valIntNew"));

        assertThrows(SchemaMismatchException.class, () -> kvBinaryView.put(Tuple.create().set("key", 1L), Tuple.create().set("unknownColumn", 10)));
    }

    /**
     * Check upsert row of old schema with row of new schema.
     */
    @Test
    public void testLiveSchemaUpsertOldSchemaRow() {
        List<Ignite> grid = startGrid();

        createTable(grid);

        Table tbl = grid.get(1).tables().table(TABLE);

        ((TableImpl)tbl).schemaType(SchemaMode.LIVE_SCHEMA);

        KeyValueBinaryView view = tbl.kvView();

        Tuple oldSchemaKey = Tuple.create().set("key", 32L);
        Tuple oldSchemaVal = Tuple.create().set("valInt", 111).set("valStr", "str");

        view.put(oldSchemaKey, oldSchemaVal);

        Tuple upsertOldSchemaVal = Tuple.create().set("valStrNew", "111").set("valIntNew", 333);

        view.put(oldSchemaKey, upsertOldSchemaVal);

        Tuple oldSchemaRes = view.get(oldSchemaKey);

        assertEquals("111", oldSchemaRes.value("valStrNew"));
        assertEquals(Integer.valueOf(333), oldSchemaRes.value("valIntNew"));
    }

    /**
     * Check upsert row of old schema with row of new schema.
     */
    @Test
    public void testLiveSchemaUpsertSchemaTwice() {
        List<Ignite> grid = startGrid();

        createTable(grid);

        Table tbl = grid.get(1).tables().table(TABLE);

        ((TableImpl)tbl).schemaType(SchemaMode.LIVE_SCHEMA);

        KeyValueBinaryView view = tbl.kvView();

        Tuple oldSchemaKey = Tuple.create().set("key", 32L);

        Tuple oldSchemaVal = Tuple.create().set("valInt", 111).set("valStr", "str");
        Tuple upsertOldSchemaVal = Tuple.create().set("valStrNew", "111").set("valIntNew", 333);
        Tuple secondUpsertOldSchemaVal = Tuple.create().set("valStrNew", "111").set("valIntNew", 333).set("anotherNewVal", 48L);

        view.put(oldSchemaKey, oldSchemaVal);
        view.put(oldSchemaKey, upsertOldSchemaVal);
        view.put(oldSchemaKey, secondUpsertOldSchemaVal);

        Tuple oldSchemaRes = view.get(oldSchemaKey);

        assertEquals("111", oldSchemaRes.value("valStrNew"));
        assertEquals(Integer.valueOf(333), oldSchemaRes.value("valIntNew"));
        assertEquals(Long.valueOf(48L), oldSchemaRes.value("anotherNewVal"));
    }

    /**
     * Check inserting row of old schema will not lead to column removal.
     */
    @Test
    public void testLiveSchemaInsertOldSchemaRow() {
        List<Ignite> grid = startGrid();

        createTable(grid);

        Table tbl = grid.get(0).tables().table(TABLE);

        ((TableImpl)tbl).schemaType(SchemaMode.LIVE_SCHEMA);

        KeyValueBinaryView view = tbl.kvView();

        Tuple oldSchemaKey = Tuple.create().set("key", 32L);
        Tuple oldSchemaVal = Tuple.create().set("valInt", 111).set("valStr", "str");

        Tuple newSchemaKey = Tuple.create().set("key", 1L);
        Tuple newSchemaVal = Tuple.create().set("valStrNew", "111").set("valIntNew", 333);

        view.put(newSchemaKey, newSchemaVal);
        view.put(oldSchemaKey, oldSchemaVal);

        Tuple res = view.get(newSchemaKey);

        assertEquals("111", res.value("valStrNew"));
        assertEquals(Integer.valueOf(333), res.value("valIntNew"));

        SchemaDescriptor schema = ((TableImpl)tbl).schemaView().schema();

        assertTrue(schema.columnNames().contains("valStrNew"));
        assertTrue(schema.columnNames().contains("valIntNew"));
    }
}
