/*
 * 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 com.mapr.drill.maprdb.tests.json;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.InputStream;
import java.util.List;

import org.apache.drill.exec.proto.UserBitShared;
import org.apache.drill.exec.proto.UserBitShared.QueryProfile;
import org.apache.drill.exec.proto.UserBitShared.QueryType;
import org.apache.drill.exec.proto.helper.QueryIdHelper;
import org.apache.drill.exec.rpc.user.AwaitableUserResultsListener;
import org.apache.drill.exec.store.sys.PersistentStore;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.ojai.Document;
import org.ojai.DocumentStream;
import org.ojai.json.Json;

import com.google.common.collect.Lists;
import com.mapr.db.Table;
import com.mapr.db.tests.utils.DBTests;
import com.mapr.drill.maprdb.tests.MaprDBTestsSuite;
import com.mapr.tests.annotations.ClusterTest;

@Category(ClusterTest.class)
public class TestScanRanges extends BaseJsonTest {
  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestScanRanges.class);

  private static final int TOTAL_ROW_COUNT = 1000000;
  private static final String TABLE_NAME = "large_table_TestScanRanges";
  private static final String JSON_FILE_URL = "/com/mapr/drill/json/business.json";

  private static boolean tableCreated = false;
  private static String tablePath;
  protected String getTablePath() {
    return tablePath;
  }

  @BeforeClass
  public static void setup_TestSimpleJson() throws Exception {
    // We create a large table with auto-split set to disabled.
    // Without intra-tablet partitioning, this test should run with only one minor fragment
    try (Table table = DBTests.createOrReplaceTable(TABLE_NAME, false /*autoSplit*/);
         InputStream in = MaprDBTestsSuite.getJsonStream(JSON_FILE_URL);
         DocumentStream stream = Json.newDocumentStream(in)) {
      tableCreated = true;
      tablePath = table.getPath().toUri().getPath();

      List<Document> docs = Lists.newArrayList(stream);
      for (char ch = 'A'; ch <= 'T'; ch++) {
        for (int rowIndex = 0; rowIndex < 5000; rowIndex++) {
          for (int i = 0; i < docs.size(); i++) {
            final Document document = docs.get(i);
            final String id = String.format("%c%010d%03d", ch, rowIndex, i);
            document.set("documentId", rowIndex);
            table.insertOrReplace(id, document);
          }
        }
      }
      table.flush();
      DBTests.waitForRowCount(table.getPath(), TOTAL_ROW_COUNT);

      setSessionOption("planner.width.max_per_node", 5);
    }
  }

  @AfterClass
  public static void cleanup_TestEncodedFieldPaths() throws Exception {
    if (tableCreated) {
      DBTests.deleteTables(TABLE_NAME);
    }
  }

  @Test
  public void test_scan_ranges() throws Exception {
    final PersistentStore<UserBitShared.QueryProfile> completed = getDrillbitContext().getProfileStoreContext().getCompletedProfileStore();

    setColumnWidths(new int[] {25, 40, 25, 45});
    final String sql = format("SELECT\n"
        + "  *\n"
        + "FROM\n"
        + "  %s.`%s` business");

    final SilentListener resultListener = new SilentListener();
    final AwaitableUserResultsListener listener = new AwaitableUserResultsListener(resultListener);
    testWithListener(QueryType.SQL, sql, listener);
    listener.await();

    assertEquals(TOTAL_ROW_COUNT, resultListener.getRowCount());
    String queryId = QueryIdHelper.getQueryId(resultListener.getQueryId());

    QueryProfile profile = completed.get(queryId);
    String profileString = String.valueOf(profile);
    logger.debug(profileString);
    assertNotNull(profile);
    assertTrue(profile.getTotalFragments() >= 5); // should at least as many as
  }

  @Test
  public void test_scan_ranges_with_filter_on_id() throws Exception {
    setColumnWidths(new int[] {25, 25, 25});
    final String sql = format("SELECT\n"
        + "  _id, business_id, city\n"
        + "FROM\n"
        + "  %s.`%s` business\n"
        + "WHERE\n"
        + " _id > 'M' AND _id < 'Q'");

    final SilentListener resultListener = new SilentListener();
    final AwaitableUserResultsListener listener = new AwaitableUserResultsListener(resultListener);
    testWithListener(QueryType.SQL, sql, listener);
    listener.await();

    assertEquals(200000, resultListener.getRowCount());
  }

  @Test
  public void test_scan_ranges_with_filter_on_non_id_field() throws Exception {
    setColumnWidths(new int[] {25, 25, 25});
    final String sql = format("SELECT\n"
        + "  _id, business_id, documentId\n"
        + "FROM\n"
        + "  %s.`%s` business\n"
        + "WHERE\n"
        + " documentId >= 100 AND documentId < 150");

    final SilentListener resultListener = new SilentListener();
    final AwaitableUserResultsListener listener = new AwaitableUserResultsListener(resultListener);
    testWithListener(QueryType.SQL, sql, listener);
    listener.await();

    assertEquals(10000, resultListener.getRowCount());
  }

}
