/*
 * 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.server.master.state;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;

import org.apache.accumulo.core.data.TableId;
import org.apache.accumulo.core.dataImpl.KeyExtent;
import org.apache.hadoop.io.DataInputBuffer;
import org.apache.hadoop.io.DataOutputBuffer;
import org.apache.hadoop.io.Text;
import org.junit.Before;
import org.junit.Test;

public class MergeInfoTest {

  private KeyExtent keyExtent;
  private MergeInfo mi;

  @Before
  public void setUp() {
    keyExtent = createMock(KeyExtent.class);
  }

  @Test
  public void testConstruction_NoArgs() {
    mi = new MergeInfo();
    assertEquals(MergeState.NONE, mi.getState());
    assertNull(mi.getExtent());
    assertEquals(MergeInfo.Operation.MERGE, mi.getOperation());
    assertFalse(mi.isDelete());
  }

  @Test
  public void testConstruction_2Args() {
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.DELETE);
    assertEquals(MergeState.NONE, mi.getState());
    assertSame(keyExtent, mi.getExtent());
    assertEquals(MergeInfo.Operation.DELETE, mi.getOperation());
    assertTrue(mi.isDelete());
  }

  @Test
  public void testSerialization() throws Exception {
    String table = "table";
    Text endRow = new Text("end");
    Text prevEndRow = new Text("begin");
    keyExtent = new KeyExtent(TableId.of(table), endRow, prevEndRow);
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.DELETE);
    mi.setState(MergeState.STARTED);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    mi.write(dos);
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    DataInputStream dis = new DataInputStream(bais);
    mi = new MergeInfo();
    mi.readFields(dis);
    assertSame(MergeState.STARTED, mi.getState());
    assertEquals(keyExtent, mi.getExtent());
    assertSame(MergeInfo.Operation.DELETE, mi.getOperation());
  }

  @Test
  public void testNeedsToBeChopped_DifferentTables() {
    expect(keyExtent.tableId()).andReturn(TableId.of("table1"));
    replay(keyExtent);
    KeyExtent keyExtent2 = createMock(KeyExtent.class);
    expect(keyExtent2.tableId()).andReturn(TableId.of("table2"));
    replay(keyExtent2);
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.MERGE);
    assertFalse(mi.needsToBeChopped(keyExtent2));
  }

  @Test
  public void testNeedsToBeChopped_NotDelete() {
    expect(keyExtent.tableId()).andReturn(TableId.of("table1"));
    KeyExtent keyExtent2 = createMock(KeyExtent.class);
    expect(keyExtent2.tableId()).andReturn(TableId.of("table1"));
    replay(keyExtent2);
    expect(keyExtent.overlaps(keyExtent2)).andReturn(true);
    replay(keyExtent);
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.MERGE);
    assertTrue(mi.needsToBeChopped(keyExtent2));
  }

  @Test
  public void testNeedsToBeChopped_Delete_NotFollowing() {
    testNeedsToBeChopped_Delete("somerow", false);
  }

  @Test
  public void testNeedsToBeChopped_Delete_Following() {
    testNeedsToBeChopped_Delete("prev", true);
  }

  @Test
  public void testNeedsToBeChopped_Delete_NoPrevEndRow() {
    testNeedsToBeChopped_Delete(null, false);
  }

  private void testNeedsToBeChopped_Delete(String prevEndRow, boolean expected) {
    expect(keyExtent.tableId()).andReturn(TableId.of("table1"));
    expect(keyExtent.endRow()).andReturn(new Text("prev"));
    replay(keyExtent);
    KeyExtent keyExtent2 = createMock(KeyExtent.class);
    expect(keyExtent2.tableId()).andReturn(TableId.of("table1"));
    expect(keyExtent2.prevEndRow()).andReturn(prevEndRow != null ? new Text(prevEndRow) : null);
    expectLastCall().anyTimes();
    replay(keyExtent2);
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.DELETE);
    assertEquals(expected, mi.needsToBeChopped(keyExtent2));
  }

  @Test
  public void testOverlaps_ExtentsOverlap() {
    KeyExtent keyExtent2 = createMock(KeyExtent.class);
    expect(keyExtent.overlaps(keyExtent2)).andReturn(true);
    replay(keyExtent);
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.MERGE);
    assertTrue(mi.overlaps(keyExtent2));
  }

  @Test
  public void testOverlaps_DoesNotNeedChopping() {
    KeyExtent keyExtent2 = createMock(KeyExtent.class);
    expect(keyExtent.overlaps(keyExtent2)).andReturn(false);
    expect(keyExtent.tableId()).andReturn(TableId.of("table1"));
    replay(keyExtent);
    expect(keyExtent2.tableId()).andReturn(TableId.of("table2"));
    replay(keyExtent2);
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.MERGE);
    assertFalse(mi.overlaps(keyExtent2));
  }

  @Test
  public void testOverlaps_NeedsChopping() {
    KeyExtent keyExtent2 = createMock(KeyExtent.class);
    expect(keyExtent.overlaps(keyExtent2)).andReturn(false);
    expect(keyExtent.tableId()).andReturn(TableId.of("table1"));
    expect(keyExtent.endRow()).andReturn(new Text("prev"));
    replay(keyExtent);
    expect(keyExtent2.tableId()).andReturn(TableId.of("table1"));
    expect(keyExtent2.prevEndRow()).andReturn(new Text("prev"));
    expectLastCall().anyTimes();
    replay(keyExtent2);
    mi = new MergeInfo(keyExtent, MergeInfo.Operation.DELETE);
    assertTrue(mi.overlaps(keyExtent2));
  }

  private static MergeInfo readWrite(MergeInfo info) throws Exception {
    DataOutputBuffer buffer = new DataOutputBuffer();
    info.write(buffer);
    DataInputBuffer in = new DataInputBuffer();
    in.reset(buffer.getData(), 0, buffer.getLength());
    MergeInfo info2 = new MergeInfo();
    info2.readFields(in);
    assertEquals(info.getExtent(), info2.getExtent());
    assertEquals(info.getState(), info2.getState());
    assertEquals(info.getOperation(), info2.getOperation());
    return info2;
  }

  private static KeyExtent ke(String tableId, String endRow, String prevEndRow) {
    return new KeyExtent(TableId.of(tableId), endRow == null ? null : new Text(endRow),
        prevEndRow == null ? null : new Text(prevEndRow));
  }

  @Test
  public void testWritable() throws Exception {
    MergeInfo info;
    info = readWrite(new MergeInfo(ke("a", null, "b"), MergeInfo.Operation.MERGE));
    info = readWrite(new MergeInfo(ke("a", "b", null), MergeInfo.Operation.MERGE));
    info = readWrite(new MergeInfo(ke("x", "b", "a"), MergeInfo.Operation.MERGE));
    info = readWrite(new MergeInfo(ke("x", "b", "a"), MergeInfo.Operation.DELETE));
    assertTrue(info.isDelete());
    info.setState(MergeState.COMPLETE);
  }

  @Test
  public void testNeedsToBeChopped() {
    MergeInfo info = new MergeInfo(ke("x", "b", "a"), MergeInfo.Operation.DELETE);
    assertTrue(info.needsToBeChopped(ke("x", "c", "b")));
    assertTrue(info.overlaps(ke("x", "c", "b")));
    assertFalse(info.needsToBeChopped(ke("y", "c", "b")));
    assertFalse(info.needsToBeChopped(ke("x", "c", "bb")));
    assertFalse(info.needsToBeChopped(ke("x", "b", "a")));
    info = new MergeInfo(ke("x", "b", "a"), MergeInfo.Operation.MERGE);
    assertTrue(info.needsToBeChopped(ke("x", "c", "a")));
    assertTrue(info.needsToBeChopped(ke("x", "aa", "a")));
    assertTrue(info.needsToBeChopped(ke("x", null, null)));
    assertFalse(info.needsToBeChopped(ke("x", "c", "b")));
    assertFalse(info.needsToBeChopped(ke("y", "c", "b")));
    assertFalse(info.needsToBeChopped(ke("x", "c", "bb")));
    assertTrue(info.needsToBeChopped(ke("x", "b", "a")));
  }

}
