// 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.googlesource.gerrit.plugins.replication;

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

import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.WaitUtil;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.git.WorkQueue;
import java.time.Duration;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.URIish;
import org.junit.Test;

/**
 * The tests in this class ensure the correctness of {@link
 * com.googlesource.gerrit.plugins.replication.ReplicationQueue.Distributor}
 */
@UseLocalDisk
@TestPlugin(
    name = "replication",
    sysModule = "com.googlesource.gerrit.plugins.replication.ReplicationModule")
public class ReplicationDistributorIT extends ReplicationStorageDaemon {
  private static final int TEST_DISTRIBUTION_INTERVAL_SECONDS = 3;
  private static final int TEST_DISTRIBUTION_DURATION_SECONDS = 1;
  private static final int TEST_DISTRIBUTION_CYCLE_SECONDS =
      TEST_DISTRIBUTION_INTERVAL_SECONDS + TEST_DISTRIBUTION_DURATION_SECONDS;

  @Override
  public void setUpTestPlugin() throws Exception {
    initConfig();
    setDistributionInterval(TEST_DISTRIBUTION_INTERVAL_SECONDS);
    super.setUpTestPlugin();
  }

  @Test
  public void distributorAddingTaskFromStorage() throws Exception {
    String remote = "foo";
    String replica = "replica";
    String master = "refs/heads/master";
    String newBranch = "refs/heads/foo_branch";
    Project.NameKey targetProject = createTestProject(project + replica);
    ReplicationTasksStorage.ReplicateRefUpdate ref =
        ReplicationTasksStorage.ReplicateRefUpdate.create(
            project.get(), newBranch, new URIish(getProjectUri(targetProject)), remote);
    createBranch(project, master, newBranch);
    setReplicationDestination(remote, replica, ALL_PROJECTS);
    reloadConfig();

    tasksStorage.create(ref); // Mimics RefUpdate inserted into storage by other Primary
    WaitUtil.waitUntil(
        () -> getProjectTasks().size() != 0, Duration.ofSeconds(TEST_DISTRIBUTION_CYCLE_SECONDS));

    List<WorkQueue.Task<?>> tasks = getProjectTasks();
    assertThat(tasks).hasSize(1); // ReplicationTask for the created ref in queue
    assertThat(waitForProjectTaskCount(0, TEST_PUSH_TIMEOUT)).isTrue();

    try (Repository targetRepo = repoManager.openRepository(targetProject);
        Repository sourceRepo = repoManager.openRepository(project)) {
      Ref masterRef = getRef(sourceRepo, master);
      Ref targetBranchRef = getRef(targetRepo, newBranch);
      assertThat(targetBranchRef).isNotNull();
      assertThat(targetBranchRef.getObjectId()).isEqualTo(masterRef.getObjectId());
    }
  }

  @Test
  public void distributorPrunesTaskFromWorkQueue() throws Exception {
    createTestProject(project + "replica");
    setReplicationDestination("foo", "replica", ALL_PROJECTS, Integer.MAX_VALUE);
    reloadConfig();

    String newBranch = "refs/heads/foo_branch";
    createBranch(BranchNameKey.create(project, newBranch));

    assertThat(listWaitingReplicationTasks(newBranch)).hasSize(1);
    deleteWaitingReplicationTasks(newBranch); // This simulates the work being started by other node

    assertThat(waitForProjectTaskCount(0, Duration.ofSeconds(TEST_DISTRIBUTION_CYCLE_SECONDS)))
        .isTrue();
  }

  private List<WorkQueue.Task<?>> getProjectTasks() {
    return getInstance(WorkQueue.class).getTasks().stream()
        .filter(t -> t instanceof WorkQueue.ProjectTask)
        .collect(Collectors.toList());
  }

  private void createBranch(Project.NameKey project, String fromRef, String refToCreate)
      throws Exception {
    try (Repository repo = repoManager.openRepository(project)) {
      Ref from = repo.exactRef(fromRef);
      RefUpdate createBranch = repo.updateRef(refToCreate);
      createBranch.setNewObjectId(from.getObjectId());
      createBranch.update();
    }
  }

  private boolean waitForProjectTaskCount(int count, Duration duration) {
    try {
      WaitUtil.waitUntil(() -> getProjectTasks().size() == count, duration);
      return true;
    } catch (InterruptedException e) {
      return false;
    }
  }
}
