/*
 * 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.accumulo.test.functional;

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.harness.AccumuloClusterHarness;
import org.apache.hadoop.io.Text;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Iterators;

public class DeleteRowsIT extends AccumuloClusterHarness {

  @Override
  protected int defaultTimeoutSeconds() {
    return 5 * 60;
  }

  private static final Logger log = LoggerFactory.getLogger(DeleteRowsIT.class);

  private static final int ROWS_PER_TABLET = 10;
  private static final String[] LETTERS = new String[] {"a", "b", "c", "d", "e", "f", "g", "h", "i",
      "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
  static final SortedSet<Text> SPLITS = new TreeSet<>();
  static {
    for (String alpha : LETTERS) {
      SPLITS.add(new Text(alpha));
    }
  }
  static final List<String> ROWS = new ArrayList<>(Arrays.asList(LETTERS));
  static {
    // put data on first and last tablet
    ROWS.add("A");
    ROWS.add("{");
  }

  @Test
  public void testDeleteAllRows() throws Exception {
    Connector c = getConnector();
    String[] tableNames = this.getUniqueNames(20);
    for (String tableName : tableNames) {
      c.tableOperations().create(tableName);
      c.tableOperations().deleteRows(tableName, null, null);
      Scanner scanner = c.createScanner(tableName, Authorizations.EMPTY);
      assertEquals(0, Iterators.size(scanner.iterator()));
    }
  }

  @Test
  public void testManyRows() throws Exception {
    // Delete ranges of rows, and verify the tablets are removed.
    int i = 0;
    // Eliminate whole tablets
    String tableName = getUniqueNames(1)[0];
    testSplit(tableName + i++, "f", "h", "abcdefijklmnopqrstuvwxyz", 260);
    // Eliminate whole tablets, partial first tablet
    testSplit(tableName + i++, "f1", "h", "abcdeff1ijklmnopqrstuvwxyz", 262);
    // Eliminate whole tablets, partial last tablet
    testSplit(tableName + i++, "f", "h1", "abcdefijklmnopqrstuvwxyz", 258);
    // Eliminate whole tablets, partial first and last tablet
    testSplit(tableName + i++, "f1", "h1", "abcdeff1ijklmnopqrstuvwxyz", 260);
    // Eliminate one tablet
    testSplit(tableName + i++, "f", "g", "abcdefhijklmnopqrstuvwxyz", 270);
    // Eliminate partial tablet, matches start split
    testSplit(tableName + i++, "f", "f1", "abcdefghijklmnopqrstuvwxyz", 278);
    // Eliminate partial tablet, matches end split
    testSplit(tableName + i++, "f1", "g", "abcdeff1hijklmnopqrstuvwxyz", 272);
    // Eliminate tablets starting at -inf
    testSplit(tableName + i++, null, "h", "ijklmnopqrstuvwxyz", 200);
    // Eliminate tablets ending at +inf
    testSplit(tableName + i++, "t", null, "abcdefghijklmnopqrst", 200);
    // Eliminate some rows inside one tablet
    testSplit(tableName + i++, "t0", "t2", "abcdefghijklmnopqrstt0uvwxyz", 278);
    // Eliminate some rows in the first tablet
    testSplit(tableName + i++, null, "A1", "abcdefghijklmnopqrstuvwxyz", 278);
    // Eliminate some rows in the last tablet
    testSplit(tableName + i++, "{1", null, "abcdefghijklmnopqrstuvwxyz{1", 272);
    // Delete everything
    testSplit(tableName + i++, null, null, "", 0);
  }

  private void testSplit(String table, String start, String end, String result, int entries)
      throws Exception {
    // Put a bunch of rows on each tablet
    Connector c = getConnector();
    c.tableOperations().create(table);
    BatchWriter bw = c.createBatchWriter(table, null);
    for (String row : ROWS) {
      for (int j = 0; j < ROWS_PER_TABLET; j++) {
        Mutation m = new Mutation(row + j);
        m.put("cf", "cq", "value");
        bw.addMutation(m);
      }
    }
    bw.flush();
    bw.close();
    // Split the table
    c.tableOperations().addSplits(table, SPLITS);

    Text startText = start == null ? null : new Text(start);
    Text endText = end == null ? null : new Text(end);
    c.tableOperations().deleteRows(table, startText, endText);
    Collection<Text> remainingSplits = c.tableOperations().listSplits(table);
    StringBuilder sb = new StringBuilder();
    // See that whole tablets are removed
    for (Text split : remainingSplits)
      sb.append(split.toString());
    assertEquals(result, sb.toString());
    // See that the rows are really deleted
    Scanner scanner = c.createScanner(table, Authorizations.EMPTY);
    int count = 0;
    for (Entry<Key,Value> entry : scanner) {
      Text row = entry.getKey().getRow();
      assertTrue((startText == null || row.compareTo(startText) <= 0)
          || (endText == null || row.compareTo(endText) > 0));
      assertTrue(startText != null || endText != null);
      count++;
    }
    log.info("Finished table " + table);
    assertEquals(entries, count);
  }

}
