/*
 * 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;

import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;

import org.apache.accumulo.core.cli.ClientOpts;
import org.apache.accumulo.core.client.Accumulo;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.data.Column;
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.core.security.ColumnVisibility;
import org.apache.accumulo.core.util.TextUtil;
import org.apache.hadoop.io.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.beust.jcommander.Parameter;

public class TestRandomDeletes {
  private static final Logger log = LoggerFactory.getLogger(TestRandomDeletes.class);
  private static Authorizations auths = new Authorizations("L1", "L2", "G1", "GROUP2");

  private static class RowColumn implements Comparable<RowColumn> {
    Text row;
    Column column;
    long timestamp;

    public RowColumn(Text row, Column column, long timestamp) {
      this.row = row;
      this.column = column;
      this.timestamp = timestamp;
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(row) + Objects.hashCode(column);
    }

    @Override
    public boolean equals(Object obj) {
      return this == obj
          || (obj != null && obj instanceof RowColumn && compareTo((RowColumn) obj) == 0);
    }

    @Override
    public int compareTo(RowColumn other) {
      int result = row.compareTo(other.row);
      if (result != 0)
        return result;
      return column.compareTo(other.column);
    }

    @Override
    public String toString() {
      return row + ":" + column;
    }
  }

  private static TreeSet<RowColumn> scanAll(TestOpts opts) throws Exception {
    TreeSet<RowColumn> result = new TreeSet<>();
    try (AccumuloClient client = Accumulo.newClient().from(opts.getClientProps()).build();
        Scanner scanner = client.createScanner(opts.tableName, auths)) {
      for (Entry<Key,Value> entry : scanner) {
        Key key = entry.getKey();
        Column column = new Column(TextUtil.getBytes(key.getColumnFamily()),
            TextUtil.getBytes(key.getColumnQualifier()),
            TextUtil.getBytes(key.getColumnVisibility()));
        result.add(new RowColumn(key.getRow(), column, key.getTimestamp()));
      }
    }
    return result;
  }

  private static long scrambleDeleteHalfAndCheck(TestOpts opts, Set<RowColumn> rows)
      throws Exception {
    int result = 0;
    ArrayList<RowColumn> entries = new ArrayList<>(rows);
    java.util.Collections.shuffle(entries);

    try (AccumuloClient client = Accumulo.newClient().from(opts.getClientProps()).build();
        BatchWriter bw = client.createBatchWriter(opts.tableName)) {

      for (int i = 0; i < (entries.size() + 1) / 2; i++) {
        RowColumn rc = entries.get(i);
        Mutation m = new Mutation(rc.row);
        m.putDelete(new Text(rc.column.columnFamily), new Text(rc.column.columnQualifier),
            new ColumnVisibility(rc.column.getColumnVisibility()), rc.timestamp + 1);
        bw.addMutation(m);
        rows.remove(rc);
        result++;
      }
    }

    Set<RowColumn> current = scanAll(opts);
    current.removeAll(rows);
    if (!current.isEmpty()) {
      throw new RuntimeException(current.size() + " records not deleted");
    }
    return result;
  }

  static class TestOpts extends ClientOpts {
    @Parameter(names = "--table", description = "table to use")
    String tableName = "test_ingest";
  }

  public static void main(String[] args) {

    TestOpts opts = new TestOpts();
    opts.parseArgs(TestRandomDeletes.class.getName(), args);

    log.info("starting random delete test");

    try {
      long deleted = 0;

      TreeSet<RowColumn> doomed = scanAll(opts);
      log.info("Got {} rows", doomed.size());

      long startTime = System.currentTimeMillis();
      while (true) {
        long half = scrambleDeleteHalfAndCheck(opts, doomed);
        deleted += half;
        if (half == 0)
          break;
      }
      long stopTime = System.currentTimeMillis();

      long elapsed = (stopTime - startTime) / 1000;
      log.info("deleted {} values in {} seconds", deleted, elapsed);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}
