/**
 * 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.hadoop.fs;

import org.junit.Test;
import static org.junit.Assert.*;

public class TestVolumeId {

  @Test
  public void testEquality() {
    final VolumeId id1 = new HdfsVolumeId(new byte[] { (byte)0, (byte)0 });
    testEq(true, id1, id1);

    final VolumeId id2 = new HdfsVolumeId(new byte[] { (byte)0, (byte)1 });
    testEq(true, id2, id2);
    testEq(false, id1, id2);

    final VolumeId id3 = new HdfsVolumeId(new byte[] { (byte)1, (byte)0 });
    testEq(true, id3, id3);
    testEq(false, id1, id3);
    
    // same as 2, but "invalid":
    final VolumeId id2copy1 = new HdfsVolumeId(new byte[] { (byte)0, (byte)1 });
    
    testEq(true, id2, id2copy1);

    // same as 2copy1: 
    final VolumeId id2copy2 = new HdfsVolumeId(new byte[] { (byte)0, (byte)1 });
    
    testEq(true, id2, id2copy2);
    
    testEqMany(true, new VolumeId[] { id2, id2copy1, id2copy2 });
    
    testEqMany(false, new VolumeId[] { id1, id2, id3 });
  }
  
  @SuppressWarnings("unchecked")
  private <T> void testEq(final boolean eq, Comparable<T> id1, Comparable<T> id2) {
    final int h1 = id1.hashCode();
    final int h2 = id2.hashCode();
    
    // eq reflectivity:
    assertTrue(id1.equals(id1));
    assertTrue(id2.equals(id2));
    assertEquals(0, id1.compareTo((T)id1));
    assertEquals(0, id2.compareTo((T)id2));

    // eq symmetry:
    assertEquals(eq, id1.equals(id2));
    assertEquals(eq, id2.equals(id1));
    
    // null comparison:
    assertFalse(id1.equals(null));
    assertFalse(id2.equals(null));
    
    // compareTo:
    assertEquals(eq, 0 == id1.compareTo((T)id2));
    assertEquals(eq, 0 == id2.compareTo((T)id1));
    // compareTo must be antisymmetric:
    assertEquals(sign(id1.compareTo((T)id2)), -sign(id2.compareTo((T)id1)));
    
    // compare with null should never return 0 to be consistent with #equals(): 
    assertTrue(id1.compareTo(null) != 0);
    assertTrue(id2.compareTo(null) != 0);
    
    // check that hash codes did not change:
    assertEquals(h1, id1.hashCode());
    assertEquals(h2, id2.hashCode());
    if (eq) {
      // in this case the hash codes must be the same:
      assertEquals(h1, h2);
    }
  }
  
  private static int sign(int x) {
    if (x == 0) {
      return 0;
    } else if (x > 0) {
      return 1;
    } else {
      return -1;
    }
  }
  
  @SuppressWarnings("unchecked")
  private <T> void testEqMany(final boolean eq, Comparable<T>... volumeIds) {
    Comparable<T> vidNext;
    int sum = 0;
    for (int i=0; i<volumeIds.length; i++) {
      if (i == volumeIds.length - 1) {
        vidNext = volumeIds[0];
      } else {
        vidNext = volumeIds[i + 1];
      }
      testEq(eq, volumeIds[i], vidNext);
      sum += sign(volumeIds[i].compareTo((T)vidNext));
    }
    // the comparison relationship must always be acyclic:
    assertTrue(sum < volumeIds.length);
  }

  /*
   * Test HdfsVolumeId(new byte[0]) instances: show that we permit such
   * objects, they are still valid, and obey the same equality
   * rules other objects do. 
   */
  @Test
  public void testIdEmptyBytes() {
    final VolumeId idEmpty1   = new HdfsVolumeId(new byte[0]);
    assertTrue(idEmpty1.isValid());
    final VolumeId idEmpty2   = new HdfsVolumeId(new byte[0]);
    assertTrue(idEmpty2.isValid());
    final VolumeId idNotEmpty = new HdfsVolumeId(new byte[] { (byte)1 });
    assertTrue(idNotEmpty.isValid());
    
    testEq(true, idEmpty1, idEmpty2);
    testEq(false, idEmpty1, idNotEmpty);
    testEq(false, idEmpty2, idNotEmpty);
  }
  
  /*
   * Test the VolumeId.INVALID_VOLUME_ID singleton.
   */
  @Test
  public void testInvalidId() {
    try {
      new HdfsVolumeId(null);
      assertTrue("NPE expected.", false);
    } catch (NullPointerException npe) {
      // okay
    }
    final VolumeId idEmpty   = new HdfsVolumeId(new byte[] {});
    final VolumeId idNotEmpty = new HdfsVolumeId(new byte[] { (byte)1 });
    
    testEq(false, VolumeId.INVALID_VOLUME_ID, idNotEmpty);
    testEq(false, VolumeId.INVALID_VOLUME_ID, idEmpty);
    
    testEqMany(true, 
        new VolumeId[] { 
          VolumeId.INVALID_VOLUME_ID, 
          VolumeId.INVALID_VOLUME_ID, 
          VolumeId.INVALID_VOLUME_ID } );
    testEqMany(false, 
        new VolumeId[] {
          VolumeId.INVALID_VOLUME_ID, 
          idEmpty, 
          idNotEmpty });
  }
  
  /*
   * test #toString() for typical VolumeId equality classes
   */
  @Test
  public void testToString() {
    // The #toString() return value is only checked for != null.
    // We cannot assert more.
    String strInvalid = VolumeId.INVALID_VOLUME_ID.toString();
    assertNotNull(strInvalid);
    
    String strEmpty = new HdfsVolumeId(new byte[] {}).toString();
    assertNotNull(strEmpty);
    
    String strNotEmpty = new HdfsVolumeId(new byte[] { (byte)1 }).toString();
    assertNotNull(strNotEmpty);
  } 
  
}
