/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.wire;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertSame;

import alluxio.network.TieredIdentityFactory;
import alluxio.util.CommonUtils;
import alluxio.wire.TieredIdentity.LocalityTier;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * Unit tests for {@link TieredIdentity}.
 */
public class TieredIdentityTest {

  @Test
  public void nearest() throws Exception {
    TieredIdentity id1 = TieredIdentityFactory.fromString("node=A,rack=rack1");
    TieredIdentity id2 = TieredIdentityFactory.fromString("node=B,rack=rack2");
    TieredIdentity id3 = TieredIdentityFactory.fromString("node=C,rack=rack2");
    List<TieredIdentity> identities = Arrays.asList(id1, id2, id3);

    assertSame(id1,
        TieredIdentityFactory.fromString("node=D,rack=rack1").nearest(identities).get());
    assertSame(id2,
        TieredIdentityFactory.fromString("node=B,rack=rack2").nearest(identities).get());
    assertSame(id3,
        TieredIdentityFactory.fromString("node=C,rack=rack2").nearest(identities).get());
    assertSame(id1,
        TieredIdentityFactory.fromString("node=D,rack=rack3").nearest(identities).get());
  }

  @Test
  public void json() throws Exception {
    TieredIdentity tieredIdentity = createRandomTieredIdentity();
    ObjectMapper mapper = new ObjectMapper();
    TieredIdentity other =
        mapper.readValue(mapper.writeValueAsBytes(tieredIdentity), TieredIdentity.class);
    checkEquality(tieredIdentity, other);
  }

  @Test
  public void thrift() {
    TieredIdentity tieredIdentity = createRandomTieredIdentity();
    TieredIdentity other = TieredIdentity.fromThrift(tieredIdentity.toThrift());
    checkEquality(tieredIdentity, other);
  }

  @Test
  public void locality() {
    LocalityTier lt1 = new LocalityTier("node", "A");
    LocalityTier lt2 = new LocalityTier("node", "A");
    LocalityTier lt3 = new LocalityTier("node", "B");
    LocalityTier lt4 = new LocalityTier("rack", "A");
    LocalityTier lt5 = new LocalityTier("rack", "B");
    LocalityTier lt6 = new LocalityTier("rack", "B");
    LocalityTier lt7 = new LocalityTier("rack", "");
    LocalityTier lt8 = new LocalityTier("node", "A");
    LocalityTier lt9 = new LocalityTier("node", "");
    assertEquals(lt1, lt1);
    assertEquals(lt1, lt2);
    assertNotEquals(lt2, lt3);
    assertEquals(lt5, lt6);
    assertNotEquals(lt4, lt5);
    assertNotEquals(lt6, lt7);
    assertNotEquals(lt8, lt9);
  }

  public void string() {
    TieredIdentity identity = new TieredIdentity(
        Arrays.asList(new LocalityTier("k1", "v1"), new LocalityTier("k2", "v2")));
    assertEquals("TieredIdentity(k1=v1, k2=v2)", identity.toString());
  }

  public void checkEquality(TieredIdentity a, TieredIdentity b) {
    assertEquals(a.getTiers(), b.getTiers());
    assertEquals(a, b);
  }

  public static TieredIdentity createRandomTieredIdentity() {
    return new TieredIdentity(
        Arrays.asList(createRandomLocalityTier(), createRandomLocalityTier()));
  }

  private static LocalityTier createRandomLocalityTier() {
    Random random = new Random();

    String tier = CommonUtils.randomAlphaNumString(random.nextInt(10) + 1);
    String value = CommonUtils.randomAlphaNumString(random.nextInt(10) + 1);
    return new LocalityTier(tier, value);
  }
}

@@ -612,25 +612,21 @@
 t.assert
-NotEqu
+F
 als
+e
 ;%0Aimport
@@ -662,16 +662,156 @@
 rtSame;%0A
+import static org.junit.Assert.assertTrue;%0A%0Aimport alluxio.Configuration;%0Aimport alluxio.ConfigurationTestUtils;%0Aimport alluxio.PropertyKey;
 %0Aimport 
@@ -984,16 +984,40 @@
 Mapper;%0A
+import org.junit.After;%0A
 import o
@@ -1191,16 +1191,103 @@
 Test %7B%0A%0A
+  @After%0A  public void after() %7B%0A    ConfigurationTestUtils.resetConfiguration();%0A  %7D%0A%0A
   @Test%0A
@@ -2665,24 +2665,94 @@
 ocality() %7B%0A
+    Configuration.set(PropertyKey.LOCALITY_COMPARE_NODE_IP, %22true%22);%0A%0A
     Locality
@@ -3237,24 +3237,30 @@
 sert
-Equals(lt1, 
+True(lt1.matches(
 lt1)
+)
 ;%0A  
@@ -3271,24 +3271,30 @@
 sert
-Equals(lt1, 
+True(lt1.matches(
 lt2)
+)
 ;%0A  
@@ -3305,27 +3305,31 @@
 sert
-NotEqu
+F
 als
+e
 (lt2
-, 
+.matches(
 lt3)
+)
 ;%0A  
@@ -3340,24 +3340,30 @@
 sert
-Equals(lt5, 
+True(lt5.matches(
 lt6)
+)
 ;%0A  
@@ -3374,27 +3374,31 @@
 sert
-NotEqu
+F
 als
+e
 (lt4
-, 
+.matches(
 lt5)
+)
 ;%0A  
@@ -3409,27 +3409,31 @@
 sert
-NotEqu
+F
 als
+e
 (lt6
-, 
+.matches(
 lt7)
+)
 ;%0A  
@@ -3444,27 +3444,31 @@
 sert
-NotEqu
+F
 als
+e
 (lt8
-, 
+.matches(
 lt9)
+)
 ;%0A  

Fix test