// 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.replicationstatus;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.extensions.restapi.Url.encode;
import static com.googlesource.gerrit.plugins.replication.ReplicationState.RefPushResult;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.config.GlobalPluginConfig;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.httpd.restapi.RestApiServlet;
import com.google.gerrit.server.config.SitePaths;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.replication.RefReplicatedEvent;
import com.googlesource.gerrit.plugins.replication.ReplicationScheduledEvent;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.Map;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.junit.Before;
import org.junit.Test;

@TestPlugin(
    name = "replication-status",
    sysModule = "com.googlesource.gerrit.plugins.replicationstatus.Module")
@UseLocalDisk
public class ReplicationStatusIT extends LightweightPluginDaemonTest {
  private static final String REF_MASTER = Constants.R_HEADS + Constants.MASTER;
  private static final String REMOTE_TAGRET_NODE = "some.remote.host";
  private static final String REMOTE_TARGET_URL_TEMPLATE = "ssh://some.remote.host/git/${name}.git";
  private static final String REMOTE_NAME = "some-remote-host";

  private static final Gson gson = newGson();

  @Inject protected SitePaths sitePaths;
  @Inject private ProjectOperations projectOperations;

  private EventHandler eventHandler;

  @Before
  public void setUp() throws IOException {
    eventHandler = plugin.getSysInjector().getInstance(EventHandler.class);
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldBeOKSuccessForAdminUsers() throws Exception {
    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));
    result.assertOK();

    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(emptyReplicationStatus(project, REMOTE_TAGRET_NODE));
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldBeOKSuccessForProjectOwners() throws Exception {
    makeProjectOwner(user, project);
    RestResponse result = userRestSession.get(endpoint(project, REMOTE_NAME));
    result.assertOK();

    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(emptyReplicationStatus(project, REMOTE_TAGRET_NODE));
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldBeForbiddenForNonProjectOwners() throws Exception {
    RestResponse result = userRestSession.get(endpoint(project, REMOTE_NAME));
    result.assertForbidden();

    assertThat(result.getEntityContent()).contains("Administrate Server or Project owner required");
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldBeForbiddenForAnonymousUsers() throws Exception {
    RestResponse result = anonymousRestSession.get(endpoint(project, REMOTE_NAME));
    result.assertForbidden();

    assertThat(result.getEntityContent()).contains("Administrate Server or Project owner required");
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldNotReportStatusOfReplicationsGeneratedOnDifferentNodes() throws Exception {
    eventHandler.onEvent(
        successReplicatedEvent("testInstanceId-2", System.currentTimeMillis(), REMOTE_TAGRET_NODE));

    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));
    result.assertOK();

    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(emptyReplicationStatus(project, REMOTE_TAGRET_NODE));
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldReturnSuccessfulProjectReplicationStatus() throws Exception {
    long eventCreatedOn = System.currentTimeMillis();

    eventHandler.onEvent(
        successReplicatedEvent("testInstanceId-1", eventCreatedOn, REMOTE_TAGRET_NODE));
    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));

    result.assertOK();
    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(successReplicationStatus(REMOTE_TAGRET_NODE, project, eventCreatedOn));
  }

  @Test
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldReturnScheduledProjectReplicationStatus() throws Exception {
    long eventCreatedOn = System.currentTimeMillis();

    eventHandler.onEvent(scheduledEvent(null, eventCreatedOn, REF_MASTER, REMOTE_TAGRET_NODE));
    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));

    result.assertOK();
    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(scheduledReplicationStatus(REMOTE_TAGRET_NODE, project, eventCreatedOn));
  }

  @Test
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldConsumeEventsThatHaveNoInstanceId() throws Exception {
    long eventCreatedOn = System.currentTimeMillis();

    eventHandler.onEvent(successReplicatedEvent(null, eventCreatedOn, REMOTE_TAGRET_NODE));
    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));

    result.assertOK();
    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(successReplicationStatus(REMOTE_TAGRET_NODE, project, eventCreatedOn));
  }

  @Test
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldNotConsumeEventsWhenNodeInstanceIdIsNullButEventHasIt() throws Exception {
    eventHandler.onEvent(
        successReplicatedEvent("testInstanceId-2", System.currentTimeMillis(), REMOTE_TAGRET_NODE));

    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));
    result.assertOK();

    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(emptyReplicationStatus(project, REMOTE_TAGRET_NODE));
  }

  @Test
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldConsumeEventsWhenBothNodeAndEventHaveNoInstanceId() throws Exception {
    long eventCreatedOn = System.currentTimeMillis();

    eventHandler.onEvent(successReplicatedEvent(null, eventCreatedOn, REMOTE_TAGRET_NODE));
    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));

    result.assertOK();
    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(successReplicationStatus(REMOTE_TAGRET_NODE, project, eventCreatedOn));
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldShowFailedInPayloadWhenRefCouldntBeReplicated() throws Exception {
    long eventCreatedOn = System.currentTimeMillis();

    eventHandler.onEvent(
        failedReplicatedEvent("testInstanceId-1", eventCreatedOn, REMOTE_TAGRET_NODE));
    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));

    result.assertOK();
    assertThat(contentWithoutMagicJson(result))
        .isEqualTo(failedReplicationStatus(REMOTE_TAGRET_NODE, project, eventCreatedOn));
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      value = REMOTE_TARGET_URL_TEMPLATE)
  public void shouldBeOKSuccessForNonExistentRemoteName() throws Exception {
    String nonExistingRemote = "non-existing-remote";
    RestResponse result = adminRestSession.get(endpoint(project, nonExistingRemote));
    result.assertOK();

    assertThat(contentWithoutMagicJson(result)).isEqualTo(emptyReplicationStatus(project));
  }

  @Test
  @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId-1")
  @GlobalPluginConfig(
      pluginName = "replication",
      name = "remote.some-remote-host.url",
      values = {REMOTE_TARGET_URL_TEMPLATE, "ssh://some.remote.host2/git/${name}.git"})
  public void shouldReturnSuccessfulProjectReplicationStatusForMultipeURLs() throws Exception {
    long eventCreatedOn = System.currentTimeMillis();

    eventHandler.onEvent(
        successReplicatedEvent("testInstanceId-1", eventCreatedOn, REMOTE_TAGRET_NODE));
    eventHandler.onEvent(
        successReplicatedEvent("testInstanceId-1", eventCreatedOn, "some.remote.host2"));
    RestResponse result = adminRestSession.get(endpoint(project, REMOTE_NAME));

    result.assertOK();
    String resultJson = contentWithoutMagicJson(result);
    Map<String, RemoteReplicationStatus> statuses =
        ImmutableMap.of(
            REMOTE_TAGRET_NODE,
            RemoteReplicationStatus.create(
                ImmutableMap.of(
                    REF_MASTER,
                    ReplicationStatus.create(
                        ReplicationStatus.ReplicationStatusResult.SUCCEEDED, eventCreatedOn))),
            "some.remote.host2",
            RemoteReplicationStatus.create(
                ImmutableMap.of(
                    REF_MASTER,
                    ReplicationStatus.create(
                        ReplicationStatus.ReplicationStatusResult.SUCCEEDED, eventCreatedOn))));
    assertThat(resultJson)
        .isEqualTo(
            projectReplicationStatus(
                statuses, project, ProjectReplicationStatus.ProjectReplicationStatusResult.OK));
  }

  private String contentWithoutMagicJson(RestResponse response) throws IOException {
    return response.getEntityContent().substring(RestApiServlet.JSON_MAGIC.length);
  }

  private AccountGroup.UUID createGroup(String name, TestAccount member) throws RestApiException {
    GroupInput groupInput = new GroupInput();
    groupInput.name = name(name);
    groupInput.members = Collections.singletonList(String.valueOf(member.id().get()));
    return AccountGroup.uuid(gApi.groups().create(groupInput).get().id);
  }

  private void makeProjectOwner(TestAccount user, Project.NameKey project) throws RestApiException {
    projectOperations
        .project(project)
        .forUpdate()
        .add(
            allow(Permission.OWNER)
                .ref(AccessSection.ALL)
                .group(createGroup("projectOwners", user)))
        .update();
  }

  private RefReplicatedEvent replicatedEvent(
      @Nullable String instanceId,
      long when,
      String ref,
      String remote,
      RefPushResult status,
      RemoteRefUpdate.Status refStatus) {
    RefReplicatedEvent replicatedEvent =
        new RefReplicatedEvent(project.get(), ref, remote, status, refStatus);
    replicatedEvent.instanceId = instanceId;
    replicatedEvent.eventCreatedOn = when;

    return replicatedEvent;
  }

  private ReplicationScheduledEvent scheduledEvent(
      @Nullable String instanceId, long when, String ref, String remote) {
    ReplicationScheduledEvent scheduledEvent =
        new ReplicationScheduledEvent(project.get(), ref, remote);
    scheduledEvent.instanceId = instanceId;
    scheduledEvent.eventCreatedOn = when;

    return scheduledEvent;
  }

  private RefReplicatedEvent successReplicatedEvent(
      @Nullable String instanceId, long when, String remoteUrl) {

    return replicatedEvent(
        instanceId,
        when,
        REF_MASTER,
        remoteUrl,
        RefPushResult.SUCCEEDED,
        RemoteRefUpdate.Status.OK);
  }

  private RefReplicatedEvent failedReplicatedEvent(
      @Nullable String instanceId, long when, String remoteUrl) {

    return replicatedEvent(
        instanceId,
        when,
        REF_MASTER,
        remoteUrl,
        RefPushResult.FAILED,
        RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD);
  }

  private static String endpoint(Project.NameKey project, String remote) {
    return String.format(
        "/projects/%s/remotes/%s/replication-status", project.get(), encode(remote));
  }

  private String emptyReplicationStatus(Project.NameKey project, String remoteUrl) {
    return emptyReplicationStatus(
        ImmutableMap.of(remoteUrl, RemoteReplicationStatus.create(Collections.emptyMap())),
        project);
  }

  private String emptyReplicationStatus(Project.NameKey project) {
    return emptyReplicationStatus(ImmutableMap.of(), project);
  }

  private String emptyReplicationStatus(
      Map<String, RemoteReplicationStatus> statuses, Project.NameKey project) {
    return gson.toJson(
        ProjectReplicationStatus.create(
            statuses, ProjectReplicationStatus.ProjectReplicationStatusResult.OK, project.get()));
  }

  private String successReplicationStatus(String remote, Project.NameKey project, long when)
      throws URISyntaxException {
    return successReplicationStatus(
        remote, project, when, ReplicationStatus.ReplicationStatusResult.SUCCEEDED);
  }

  private String scheduledReplicationStatus(String remote, Project.NameKey project, long when)
      throws URISyntaxException {
    return successReplicationStatus(
        remote, project, when, ReplicationStatus.ReplicationStatusResult.SCHEDULED);
  }

  private String successReplicationStatus(
      String remote,
      Project.NameKey project,
      long when,
      ReplicationStatus.ReplicationStatusResult replicationStatusResult)
      throws URISyntaxException {
    return projectReplicationStatus(
        remote,
        project,
        when,
        ProjectReplicationStatus.ProjectReplicationStatusResult.OK,
        replicationStatusResult);
  }

  private String failedReplicationStatus(String remote, Project.NameKey project, long when)
      throws URISyntaxException {
    return projectReplicationStatus(
        remote,
        project,
        when,
        ProjectReplicationStatus.ProjectReplicationStatusResult.FAILED,
        ReplicationStatus.ReplicationStatusResult.FAILED);
  }

  private String projectReplicationStatus(
      String remoteUrl,
      Project.NameKey project,
      long when,
      ProjectReplicationStatus.ProjectReplicationStatusResult projectReplicationStatusResult,
      ReplicationStatus.ReplicationStatusResult replicationStatusResult) {
    return projectReplicationStatus(
        ImmutableMap.of(
            remoteUrl,
            RemoteReplicationStatus.create(
                ImmutableMap.of(
                    REF_MASTER, ReplicationStatus.create(replicationStatusResult, when)))),
        project,
        projectReplicationStatusResult);
  }

  private String projectReplicationStatus(
      Map<String, RemoteReplicationStatus> statuses,
      Project.NameKey project,
      ProjectReplicationStatus.ProjectReplicationStatusResult projectReplicationStatusResult) {
    return gson.toJson(
        ProjectReplicationStatus.create(statuses, projectReplicationStatusResult, project.get()));
  }
}
