// Copyright (C) 2021 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.ericsson.gerrit.plugins.highavailability.autoreindex;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.ericsson.gerrit.plugins.highavailability.forwarder.ForwardedIndexGroupHandler;
import com.ericsson.gerrit.plugins.highavailability.forwarder.ForwardedIndexingHandler.Operation;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Account.Id;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.AccountGroup.UUID;
import com.google.gerrit.entities.AccountGroupByIdAudit;
import com.google.gerrit.entities.AccountGroupMemberAudit;
import com.google.gerrit.entities.GroupReference;
import com.google.gerrit.entities.InternalGroup;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.group.db.Groups;
import com.google.gerrit.server.util.OneOffRequestContext;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class GroupReindexRunnableTest {

  @Mock private ForwardedIndexGroupHandler indexer;
  @Mock private IndexTs indexTs;
  @Mock private OneOffRequestContext ctx;
  @Mock private Groups groups;
  @Mock private GitRepositoryManager repoManager;
  @Mock private AllUsersName allUsers;
  private GroupReference groupReference;

  private GroupReindexRunnable groupReindexRunnable;
  private static UUID uuid;

  @Before
  public void setUp() throws Exception {
    groupReindexRunnable =
        new GroupReindexRunnable(indexer, indexTs, ctx, groups, repoManager, allUsers);
    uuid = UUID.parse("123");
    groupReference = GroupReference.create(uuid, "123");
  }

  @Test
  public void groupIsIndexedWhenItIsCreatedAfterLastGroupReindex() throws Exception {
    Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());
    Timestamp afterCurrentTime = new Timestamp(currentTime.getTime() + 1000L);
    when(groups.getGroup(uuid)).thenReturn(getInternalGroup(afterCurrentTime));

    Optional<Timestamp> groupLastTs =
        groupReindexRunnable.indexIfNeeded(groupReference, currentTime);
    assertThat(groupLastTs.isPresent()).isTrue();
    assertThat(groupLastTs.get()).isEqualTo(afterCurrentTime);
    verify(indexer).index(uuid, Operation.INDEX, Optional.empty());
  }

  @Test
  public void groupIsNotIndexedWhenItIsCreatedBeforeLastGroupReindex() throws Exception {
    Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());
    Timestamp beforeCurrentTime = new Timestamp(currentTime.getTime() - 1000L);
    when(groups.getGroup(uuid)).thenReturn(getInternalGroup(beforeCurrentTime));

    Optional<Timestamp> groupLastTs =
        groupReindexRunnable.indexIfNeeded(groupReference, currentTime);
    assertThat(groupLastTs.isPresent()).isFalse();
    verify(indexer, never()).index(uuid, Operation.INDEX, Optional.empty());
  }

  @Test
  public void groupIsNotIndexedGroupReferenceNotPresent() {
    Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());
    Optional<Timestamp> groupLastTs =
        groupReindexRunnable.indexIfNeeded(groupReference, currentTime);
    assertThat(groupLastTs.isPresent()).isFalse();
  }

  @Test
  public void groupIsIndexedWhenNewUserAddedAfterLastGroupReindex() throws Exception {
    Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());
    Timestamp afterCurrentTime = new Timestamp(currentTime.getTime() + 1000L);
    when(groups.getGroup(uuid)).thenReturn(getInternalGroup(currentTime));
    when(groups.getMembersAudit(any(), any()))
        .thenReturn(
            Collections.singletonList(
                AccountGroupMemberAudit.builder()
                    .addedBy(Account.Id.tryParse("1").get())
                    .addedOn(afterCurrentTime.toInstant())
                    .memberId(Account.Id.tryParse("1").get())
                    .groupId(AccountGroup.Id.parse("1"))
                    .build()));
    Optional<Timestamp> groupLastTs =
        groupReindexRunnable.indexIfNeeded(groupReference, currentTime);
    assertThat(groupLastTs.isPresent()).isTrue();
    assertThat(groupLastTs.get()).isEqualTo(afterCurrentTime);
    verify(indexer).index(uuid, Operation.INDEX, Optional.empty());
  }

  @Test
  public void groupIsIndexedWhenUserRemovedAfterLastGroupReindex() throws Exception {
    Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());
    Timestamp afterCurrentTime = new Timestamp(currentTime.getTime() + 1000L);
    Timestamp beforeCurrentTime = new Timestamp(currentTime.getTime() - 1000L);

    AccountGroupMemberAudit accountGroupMemberAudit =
        AccountGroupMemberAudit.builder()
            .addedBy(Account.Id.tryParse("1").get())
            .addedOn(beforeCurrentTime.toInstant())
            .memberId(Account.Id.tryParse("1").get())
            .groupId(AccountGroup.Id.parse("2"))
            .removed(Account.Id.tryParse("2").get(), afterCurrentTime.toInstant())
            .build();
    when(groups.getGroup(uuid)).thenReturn(getInternalGroup(currentTime));
    when(groups.getMembersAudit(any(), any()))
        .thenReturn(Collections.singletonList(accountGroupMemberAudit));
    Optional<Timestamp> groupLastTs =
        groupReindexRunnable.indexIfNeeded(groupReference, currentTime);
    assertThat(groupLastTs.isPresent()).isTrue();
    assertThat(groupLastTs.get()).isEqualTo(afterCurrentTime);
    verify(indexer).index(uuid, Operation.INDEX, Optional.empty());
  }

  @Test
  public void groupIsIndexedWhenItIsSubGroupAddedAfterLastGroupReindex() throws Exception {
    Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());
    Timestamp afterCurrentTime = new Timestamp(currentTime.getTime() + 1000L);
    Timestamp beforeCurrentTime = new Timestamp(currentTime.getTime() - 1000L);
    when(groups.getGroup(uuid)).thenReturn(getInternalGroup(beforeCurrentTime));
    when(groups.getSubgroupsAudit(any(), any()))
        .thenReturn(
            Collections.singletonList(
                AccountGroupByIdAudit.builder()
                    .groupId(AccountGroup.Id.parse("1"))
                    .includeUuid(UUID.parse("123"))
                    .addedBy(Account.Id.tryParse("1").get())
                    .addedOn(afterCurrentTime.toInstant())
                    .build()));
    Optional<Timestamp> groupLastTs =
        groupReindexRunnable.indexIfNeeded(groupReference, currentTime);
    assertThat(groupLastTs.isPresent()).isTrue();
    assertThat(groupLastTs.get()).isEqualTo(afterCurrentTime);
    verify(indexer).index(uuid, Operation.INDEX, Optional.empty());
  }

  @Test
  public void groupIsIndexedWhenItIsSubGroupRemovedAfterLastGroupReindex() throws Exception {
    Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());
    Timestamp afterCurrentTime = new Timestamp(currentTime.getTime() + 1000L);
    Timestamp beforeCurrentTime = new Timestamp(currentTime.getTime() - 1000L);

    AccountGroupByIdAudit accountGroupByIdAud =
        AccountGroupByIdAudit.builder()
            .groupId(AccountGroup.Id.parse("1"))
            .includeUuid(UUID.parse("123"))
            .addedBy(Account.Id.tryParse("1").get())
            .addedOn(beforeCurrentTime.toInstant())
            .removed(Account.Id.tryParse("2").get(), afterCurrentTime.toInstant())
            .build();

    when(groups.getGroup(uuid)).thenReturn(getInternalGroup(beforeCurrentTime));
    when(groups.getSubgroupsAudit(any(), any()))
        .thenReturn(Collections.singletonList(accountGroupByIdAud));

    Optional<Timestamp> groupLastTs =
        groupReindexRunnable.indexIfNeeded(groupReference, currentTime);
    assertThat(groupLastTs.isPresent()).isTrue();
    assertThat(groupLastTs.get()).isEqualTo(afterCurrentTime);
    verify(indexer).index(uuid, Operation.INDEX, Optional.empty());
  }

  private Optional<InternalGroup> getInternalGroup(Timestamp timestamp) {
    return Optional.ofNullable(
        InternalGroup.builder()
            .setId(AccountGroup.Id.parse("1"))
            .setNameKey(AccountGroup.nameKey("Test"))
            .setOwnerGroupUUID(uuid)
            .setVisibleToAll(true)
            .setGroupUUID(UUID.parse("12"))
            .setCreatedOn(timestamp.toInstant())
            .setMembers(ImmutableSet.<Id>builder().build())
            .setSubgroups(ImmutableSet.<UUID>builder().build())
            .build());
  }
}
