// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed 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 com.google.enterprise.adaptor;

import static org.junit.Assert.*;

import com.google.enterprise.adaptor.AclTransform.MatchData;
import com.google.enterprise.adaptor.AclTransform.Rule;

import org.junit.Test;

import java.util.*;

/** Unit tests for {@link AclTransform}. */
public class AclTransformTest {
  private static final Acl baseAcl = new Acl.Builder()
      .setInheritFrom(new DocId("inherit place"))
      .setEverythingCaseInsensitive()
      .setPermits(Arrays.asList(
          new UserPrincipal("u1"),
          new GroupPrincipal("g1@d1"),
          new GroupPrincipal("D1\\g1"),
          new GroupPrincipal("D1/g1"),
          new GroupPrincipal("u1", "ns1"),
          new GroupPrincipal("u1@d1", "ns2")))
      .setDenies(Arrays.asList(
          new UserPrincipal("u1"),
          new GroupPrincipal("g1"),
          new GroupPrincipal("g1", "ns1")))
      .build();

  @Test
  public void testEmptyTransform() {
    assertSame(baseAcl,
        new AclTransform(Arrays.<Rule>asList()).transform(baseAcl));
  }

  @Test
  public void testNonMatchingTransform() {
    List<Rule> rules = Arrays.asList(
        new Rule(new MatchData(null, "nonmatching", null, null),
          new MatchData(null, "noprincipal", "nodomain", "nons")));
    assertEquals(baseAcl, new AclTransform(rules).transform(baseAcl));
  }

  @Test
  public void testAllMatchingTransform() {
    List<Rule> rules = Arrays.asList(
        new Rule(new MatchData(null, null, null, null),
          new MatchData(null, "anyprincipal", "anydomain", "anyns")));
    AclTransform transform = new AclTransform(rules);
    // Test null passthrough and re-use of AclTransform
    assertNull(transform.transform(null));
    assertEquals(new Acl.Builder(baseAcl)
          .setPermits(Arrays.asList(
            new UserPrincipal("anydomain\\anyprincipal", "anyns"),
            new GroupPrincipal("anyprincipal@anydomain", "anyns"),
            new GroupPrincipal("anydomain\\anyprincipal", "anyns"),
            new GroupPrincipal("anydomain/anyprincipal", "anyns")))
          .setDenies(Arrays.asList(
            new UserPrincipal("anydomain\\anyprincipal", "anyns"),
            new GroupPrincipal("anydomain\\anyprincipal", "anyns")))
          .build(),
        transform.transform(baseAcl));
  }

  @Test
  public void testAllMatchingTransformNoop() {
    List<Rule> rules = Arrays.asList(
        new Rule(new MatchData(null, null, null, null),
          new MatchData(null, null, null, null)));
    assertEquals(baseAcl, new AclTransform(rules).transform(baseAcl));
  }

  @Test
  public void testGroupMatching() {
    List<Rule> rules = Arrays.asList(
        new Rule(new MatchData(true, null, null, null),
          new MatchData(null, "anygroup", null, null)));
    assertEquals(new Acl.Builder(baseAcl)
          .setPermits(Arrays.asList(
            new UserPrincipal("u1"),
            new GroupPrincipal("anygroup@d1"),
            new GroupPrincipal("D1\\anygroup"),
            new GroupPrincipal("D1/anygroup"),
            new GroupPrincipal("anygroup", "ns1"),
            new GroupPrincipal("anygroup@d1", "ns2")))
          .setDenies(Arrays.asList(
            new UserPrincipal("u1"),
            new GroupPrincipal("anygroup", "ns1"),
            new GroupPrincipal("anygroup")))
          .build(),
        new AclTransform(rules).transform(baseAcl));
  }

  @Test
  public void testSpecificMatching() {
    List<Rule> rules = Arrays.asList(
        new Rule(new MatchData(true, "g1", "", "ns1"),
          new MatchData(null, null, "foundit", null)));
    assertEquals(new Acl.Builder(baseAcl)
          .setDenies(Arrays.asList(
            new UserPrincipal("u1"),
            new GroupPrincipal("g1"),
            new GroupPrincipal("foundit\\g1", "ns1")))
          .build(),
        new AclTransform(rules).transform(baseAcl));
  }

  @Test(expected = NullPointerException.class)
  public void testRuleNullMatch() {
    new Rule(null, new MatchData(null, null, null, null));
  }

  @Test(expected = NullPointerException.class)
  public void testRuleNullReplacement() {
    new Rule(new MatchData(null, null, null, null), null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void testRuleWithNonNullReplacementGroup() {
    new Rule(new MatchData(null, null, null, null),
        new MatchData(false, null, null, null));
  }

  @Test
  public void testToString() {
    assertEquals("AclTransform(rules=[Rule("
        + "match=MatchData(isGroup=true,name=a,domain=b,namespace=c),"
        + "replace=MatchData(isGroup=null,name=null,domain=null,namespace=null)"
        + ")])",
        new AclTransform(Arrays.asList(new Rule(
          new MatchData(true, "a", "b", "c"),
          new MatchData(null, null, null, null)))).toString());
  }

  @Test
  public void testEquals() {
    MatchData m1 = new MatchData(true, "a", "b", "c");
    MatchData m2 = new MatchData(true, new String("a"), new String("b"),
        new String("c"));
    MatchData m3 = new MatchData(false, "a", "b", "c");
    MatchData m4 = new MatchData(null, "a", "b", "c");
    MatchData m5 = new MatchData(true, "z", "b", "c");
    MatchData m6 = new MatchData(true, null, "b", "c");
    MatchData m7 = new MatchData(true, "a", "z", "c");
    MatchData m8 = new MatchData(true, "a", null, "c");
    MatchData m9 = new MatchData(true, "a", "b", "z");
    MatchData m10 = new MatchData(true, "a", "b", null);
    assertEquals(m1, m2);
    assertEquals(m1.hashCode(), m2.hashCode());
    assertFalse(m1.equals(m3));
    assertFalse(m1.equals(m4));
    assertFalse(m1.equals(m5));
    assertFalse(m1.equals(m6));
    assertFalse(m1.equals(m7));
    assertFalse(m1.equals(m8));
    assertFalse(m1.equals(m9));
    assertFalse(m1.equals(m10));
    assertFalse(m1.equals(new Object()));

    // Same as m4
    MatchData m11 = new MatchData(null, new String("a"), new String("b"),
        new String("c"));
    MatchData m12 = new MatchData(null, "a", "b", null);
    Rule r1 = new Rule(m1, m4);
    Rule r2 = new Rule(m2, m11);
    Rule r3 = new Rule(m3, m4);
    Rule r4 = new Rule(m1, m12);
    assertEquals(r1, r2);
    assertEquals(r1.hashCode(), r2.hashCode());
    assertFalse(r1.equals(r3));
    assertFalse(r1.equals(r4));
    assertFalse(r1.equals(new Object()));

    AclTransform t1 = new AclTransform(Arrays.asList(r1));
    AclTransform t2 = new AclTransform(Arrays.asList(r2));
    AclTransform t3 = new AclTransform(Arrays.asList(r3));
    AclTransform t4 = new AclTransform(Arrays.asList(r1, r1));
    assertEquals(t1, t2);
    assertEquals(t1.hashCode(), t2.hashCode());
    assertFalse(t1.equals(t3));
    assertFalse(t1.equals(t4));
    assertFalse(t1.equals(new Object()));
  }
}
