/*
 * 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.drill.exec.physical.resultSet.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.List;

import org.apache.drill.categories.RowSetTest;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.exec.physical.resultSet.ResultSetLoader;
import org.apache.drill.exec.physical.resultSet.impl.ResultSetLoaderImpl.ResultSetOptions;
import org.apache.drill.exec.physical.resultSet.project.Projections;
import org.apache.drill.exec.record.VectorContainer;
import org.apache.drill.exec.record.metadata.SchemaBuilder;
import org.apache.drill.exec.record.metadata.TupleMetadata;
import org.apache.drill.exec.vector.ValueVector;
import com.google.common.collect.Lists;
import org.apache.drill.test.SubOperatorTest;
import org.apache.drill.exec.physical.rowSet.RowSetBuilder;
import org.apache.drill.test.rowSet.RowSetUtilities;
import org.junit.Test;
import org.junit.experimental.categories.Category;

@Category(RowSetTest.class)
public class TestResultSetLoaderEmptyProject extends SubOperatorTest {

  /**
   * Verify that empty projection works: allows skipping rows and
   * reporting those rows as a batch with no vectors but with the
   * desired row count.
   */
  @Test
  public void testEmptyTopSchema() {
    List<SchemaPath> selection = Lists.newArrayList();
    TupleMetadata schema = new SchemaBuilder()
        .add("a", MinorType.INT)
        .add("b", MinorType.INT)
        .buildSchema();
    ResultSetOptions options = new ResultSetOptionBuilder()
        .projection(Projections.parse(selection))
        .readerSchema(schema)
        .build();
    ResultSetLoader rsLoader = new ResultSetLoaderImpl(fixture.allocator(), options);

    assertTrue(rsLoader.isProjectionEmpty());

    // Can't skip rows if batch not started.
    int rowCount = 100_000;
    try {
      rsLoader.skipRows(10);
      fail();
    } catch (IllegalStateException e) {
      // Expected
    }

    // Loop to skip 100,000 rows. Should occur in two batches.
    rsLoader.startBatch();
    int skipped = rsLoader.skipRows(rowCount);
    assertEquals(skipped, ValueVector.MAX_ROW_COUNT);

    VectorContainer output = rsLoader.harvest();
    assertEquals(skipped, output.getRecordCount());
    assertEquals(0, output.getNumberOfColumns());
    output.zeroVectors();

    // Second batch

    rowCount -= skipped;
    rsLoader.startBatch();
    skipped = rsLoader.skipRows(rowCount);
    assertEquals(skipped, rowCount);

    output = rsLoader.harvest();
    assertEquals(skipped, output.getRecordCount());
    assertEquals(0, output.getNumberOfColumns());
    output.zeroVectors();

    rsLoader.close();
  }

  /**
   * Verify that a disjoint schema (projection does not overlap with
   * table schema) is treated the same as an empty projection.
   */
  @Test
  public void testDisjointSchema() {
    List<SchemaPath> selection = Lists.newArrayList(
        SchemaPath.getSimplePath("a"),
        SchemaPath.getSimplePath("b"));
    TupleMetadata schema = new SchemaBuilder()
        .add("c", MinorType.INT)
        .add("d", MinorType.INT)
        .buildSchema();
    ResultSetOptions options = new ResultSetOptionBuilder()
        .projection(Projections.parse(selection))
        .readerSchema(schema)
        .build();
    ResultSetLoader rsLoader = new ResultSetLoaderImpl(fixture.allocator(), options);

    assertTrue(rsLoader.isProjectionEmpty());
    rsLoader.close();
  }

  /**
   * Verify that skip rows works even if the the projection is non-empty.
   */
  @Test
  public void testNonEmptySchema() {
    List<SchemaPath> selection = Lists.newArrayList(
        SchemaPath.getSimplePath("a"),
        SchemaPath.getSimplePath("b"));
    TupleMetadata schema = new SchemaBuilder()
        .add("a", MinorType.INT)
        .add("b", MinorType.INT)
        .buildSchema();
    ResultSetOptions options = new ResultSetOptionBuilder()
        .projection(Projections.parse(selection))
        .readerSchema(schema)
        .build();
    ResultSetLoader rsLoader = new ResultSetLoaderImpl(fixture.allocator(), options);

    assertFalse(rsLoader.isProjectionEmpty());

    // Skip 10 rows. Columns are of required types, so are filled
    // with zeros.
    rsLoader.startBatch();
    int rowCount = 10;
    rsLoader.skipRows(rowCount);

    // Verify
    RowSetBuilder builder = fixture.rowSetBuilder(schema);
    for (int i = 0; i < rowCount; i++) {
      builder.addRow(0, 0);
    }
    RowSetUtilities.verify(builder.build(), fixture.wrap(rsLoader.harvest()));

    rsLoader.close();
  }

  @Test
  public void testEmptyMapProjection() {
    List<SchemaPath> selection = Lists.newArrayList();
    TupleMetadata schema = new SchemaBuilder()
        .addMap("map")
          .add("a", MinorType.INT)
          .add("b", MinorType.INT)
          .resumeSchema()
        .buildSchema();
    ResultSetOptions options = new ResultSetOptionBuilder()
        .projection(Projections.parse(selection))
        .readerSchema(schema)
        .build();
    ResultSetLoader rsLoader = new ResultSetLoaderImpl(fixture.allocator(), options);

    assertTrue(rsLoader.isProjectionEmpty());

    // Sanity test to verify row skipping with maps
    int rowCount = 5000;
    rsLoader.startBatch();
    int skipped = rsLoader.skipRows(rowCount);
    assertEquals(skipped, rowCount);

    VectorContainer output = rsLoader.harvest();
    assertEquals(rowCount, output.getRecordCount());
    assertEquals(0, output.getNumberOfColumns());
    output.zeroVectors();

    rsLoader.close();
  }

  /**
   * Test disjoint projection, but with maps. Project top-level columns
   * a, b, when those columns actually appear in a map which is not
   * projected.
   */
  @Test
  public void testDisjointMapProjection() {
    List<SchemaPath> selection = Lists.newArrayList(
        SchemaPath.getSimplePath("a"),
        SchemaPath.getSimplePath("b"));
    TupleMetadata schema = new SchemaBuilder()
        .addMap("map")
          .add("a", MinorType.INT)
          .add("b", MinorType.INT)
          .resumeSchema()
        .buildSchema();
    ResultSetOptions options = new ResultSetOptionBuilder()
        .projection(Projections.parse(selection))
        .readerSchema(schema)
        .build();
    ResultSetLoader rsLoader = new ResultSetLoaderImpl(fixture.allocator(), options);

    assertTrue(rsLoader.isProjectionEmpty());

    rsLoader.close();
  }
}
