// Copyright (C) 2018 The Android Open Source Project
//
// 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.gerrit.common.data;

import static com.google.common.truth.Truth.assertThat;

import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroup.UUID;
import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class GroupReferenceTest extends GerritBaseTests {
  @Rule public ExpectedException exception = ExpectedException.none();

  @Test
  public void forGroupDescription() {
    String name = "foo";
    AccountGroup.UUID uuid = new AccountGroup.UUID("uuid-foo");
    GroupReference groupReference =
        GroupReference.forGroup(
            new GroupDescription.Basic() {

              @Override
              public String getUrl() {
                return null;
              }

              @Override
              public String getName() {
                return name;
              }

              @Override
              public UUID getGroupUUID() {
                return uuid;
              }

              @Override
              public String getEmailAddress() {
                return null;
              }
            });
    assertThat(groupReference.getName()).isEqualTo(name);
    assertThat(groupReference.getUUID()).isEqualTo(uuid);
  }

  @Test
  public void create() {
    AccountGroup.UUID uuid = new AccountGroup.UUID("uuid");
    String name = "foo";
    GroupReference groupReference = new GroupReference(uuid, name);
    assertThat(groupReference.getUUID()).isEqualTo(uuid);
    assertThat(groupReference.getName()).isEqualTo(name);
  }

  @Test
  public void createWithoutUuid() {
    // GroupReferences where the UUID is null are used to represent groups from project.config that
    // cannot be resolved.
    String name = "foo";
    GroupReference groupReference = new GroupReference(null, name);
    assertThat(groupReference.getUUID()).isNull();
    assertThat(groupReference.getName()).isEqualTo(name);
  }

  @Test
  public void cannotCreateWithoutName() {
    exception.expect(NullPointerException.class);
    new GroupReference(new AccountGroup.UUID("uuid"), null);
  }

  @Test
  public void isGroupReference() {
    assertThat(GroupReference.isGroupReference("foo")).isFalse();
    assertThat(GroupReference.isGroupReference("groupfoo")).isFalse();
    assertThat(GroupReference.isGroupReference("group foo")).isTrue();
    assertThat(GroupReference.isGroupReference("group foo-bar")).isTrue();
    assertThat(GroupReference.isGroupReference("group foo bar")).isTrue();
  }

  @Test
  public void extractGroupName() {
    assertThat(GroupReference.extractGroupName("foo")).isNull();
    assertThat(GroupReference.extractGroupName("groupfoo")).isNull();
    assertThat(GroupReference.extractGroupName("group foo")).isEqualTo("foo");
    assertThat(GroupReference.extractGroupName("group foo-bar")).isEqualTo("foo-bar");
    assertThat(GroupReference.extractGroupName("group foo bar")).isEqualTo("foo bar");
  }

  @Test
  public void getAndSetUuid() {
    AccountGroup.UUID uuid = new AccountGroup.UUID("uuid-foo");
    String name = "foo";
    GroupReference groupReference = new GroupReference(uuid, name);
    assertThat(groupReference.getUUID()).isEqualTo(uuid);

    AccountGroup.UUID uuid2 = new AccountGroup.UUID("uuid-bar");
    groupReference.setUUID(uuid2);
    assertThat(groupReference.getUUID()).isEqualTo(uuid2);

    // GroupReferences where the UUID is null are used to represent groups from project.config that
    // cannot be resolved.
    groupReference.setUUID(null);
    assertThat(groupReference.getUUID()).isNull();
  }

  @Test
  public void getAndSetName() {
    AccountGroup.UUID uuid = new AccountGroup.UUID("uuid-foo");
    String name = "foo";
    GroupReference groupReference = new GroupReference(uuid, name);
    assertThat(groupReference.getName()).isEqualTo(name);

    String name2 = "bar";
    groupReference.setName(name2);
    assertThat(groupReference.getName()).isEqualTo(name2);

    exception.expect(NullPointerException.class);
    groupReference.setName(null);
  }

  @Test
  public void toConfigValue() {
    String name = "foo";
    GroupReference groupReference = new GroupReference(new AccountGroup.UUID("uuid-foo"), name);
    assertThat(groupReference.toConfigValue()).isEqualTo("group " + name);
  }

  @Test
  public void testEquals() {
    AccountGroup.UUID uuid1 = new AccountGroup.UUID("uuid-foo");
    AccountGroup.UUID uuid2 = new AccountGroup.UUID("uuid-bar");
    String name1 = "foo";
    String name2 = "bar";

    GroupReference groupReference1 = new GroupReference(uuid1, name1);
    GroupReference groupReference2 = new GroupReference(uuid1, name2);
    GroupReference groupReference3 = new GroupReference(uuid2, name1);

    assertThat(groupReference1.equals(groupReference2)).isTrue();
    assertThat(groupReference1.equals(groupReference3)).isFalse();
    assertThat(groupReference2.equals(groupReference3)).isFalse();
  }

  @Test
  public void testHashcode() {
    AccountGroup.UUID uuid1 = new AccountGroup.UUID("uuid1");
    assertThat(new GroupReference(uuid1, "foo").hashCode())
        .isEqualTo(new GroupReference(uuid1, "bar").hashCode());

    // Check that the following calls don't fail with an exception.
    new GroupReference(null, "bar").hashCode();
    new GroupReference(new AccountGroup.UUID(null), "bar").hashCode();
  }
}
