// 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.pull.api;

import static com.google.common.truth.Truth.assertThat;
import static java.util.stream.Collectors.toList;

import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.SkipProjectClone;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.Project.NameKey;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.replication.CredentialsFactory;
import com.googlesource.gerrit.plugins.replication.pull.RevisionReader;
import com.googlesource.gerrit.plugins.replication.pull.Source;
import com.googlesource.gerrit.plugins.replication.pull.SourcesCollection;
import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionData;
import com.googlesource.gerrit.plugins.replication.pull.client.SourceHttpClient;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;

@SkipProjectClone
@UseLocalDisk
@TestPlugin(
    name = "pull-replication",
    sysModule = "com.googlesource.gerrit.plugins.replication.pull.PullReplicationModule",
    httpModule = "com.googlesource.gerrit.plugins.replication.pull.api.HttpModule")
public abstract class ActionITBase extends LightweightPluginDaemonTest {
  protected static final Optional<String> ALL_PROJECTS = Optional.empty();
  protected static final int TEST_REPLICATION_DELAY = 60;
  protected static final String TEST_REPLICATION_SUFFIX = "suffix1";
  protected static final String TEST_REPLICATION_REMOTE = "remote1";

  protected Path gitPath;
  protected FileBasedConfig config;
  protected FileBasedConfig secureConfig;
  protected RevisionReader revisionReader;

  @Inject private SitePaths sitePaths;
  @Inject private ProjectOperations projectOperations;
  CredentialsFactory credentials;
  Source source;
  SourceHttpClient.Factory httpClientFactory;
  String url;

  protected abstract String getURL(String projectName);

  @Override
  public void setUpTestPlugin() throws Exception {
    gitPath = sitePaths.site_path.resolve("git");

    config =
        new FileBasedConfig(sitePaths.etc_dir.resolve("replication.config").toFile(), FS.DETECTED);
    setReplicationSource(
        TEST_REPLICATION_REMOTE,
        TEST_REPLICATION_SUFFIX,
        ALL_PROJECTS); // Simulates a full replication.config initialization
    config.save();

    secureConfig =
        new FileBasedConfig(sitePaths.etc_dir.resolve("secure.config").toFile(), FS.DETECTED);
    setReplicationCredentials(TEST_REPLICATION_REMOTE, admin.username(), admin.httpPassword());
    secureConfig.save();

    super.setUpTestPlugin();

    httpClientFactory = plugin.getSysInjector().getInstance(SourceHttpClient.Factory.class);
    credentials = plugin.getSysInjector().getInstance(CredentialsFactory.class);
    revisionReader = plugin.getSysInjector().getInstance(RevisionReader.class);
    source = plugin.getSysInjector().getInstance(SourcesCollection.class).getAll().get(0);

    url = getURL(project.get());
  }

  protected HttpPost createRequest(String sendObjectPayload) {
    HttpPost post = new HttpPost(url);
    post.setEntity(new StringEntity(sendObjectPayload, StandardCharsets.UTF_8));
    post.addHeader(new BasicHeader("Content-Type", "application/json"));
    return post;
  }

  protected HttpPut createPutRequest(String sendObjectPayload) {
    HttpPut put = new HttpPut(url);
    put.setEntity(new StringEntity(sendObjectPayload, StandardCharsets.UTF_8));
    put.addHeader(new BasicHeader("Content-Type", "application/json"));
    return put;
  }

  protected String createRef() throws Exception {
    return createRef(Project.nameKey(project + TEST_REPLICATION_SUFFIX));
  }

  protected String createRef(NameKey projectName) throws Exception {
    testRepo = cloneProject(createTestProject(projectName.get()));

    Result pushResult = createChange("topic", "test.txt", "test_content");
    return RefNames.changeMetaRef(pushResult.getChange().getId());
  }

  protected Optional<RevisionData> createRevisionData(String refName) throws Exception {
    return createRevisionData(Project.nameKey(project + TEST_REPLICATION_SUFFIX), refName);
  }

  protected Optional<RevisionData> createRevisionData(NameKey projectName, String refName)
      throws Exception {
    return revisionReader.read(projectName, refName);
  }

  protected Object encode(byte[] content) {
    return Base64.getEncoder().encodeToString(content);
  }

  public ResponseHandler<Object> assertHttpResponseCode(int responseCode) {
    return new ResponseHandler<Object>() {

      @Override
      public Object handleResponse(HttpResponse response)
          throws ClientProtocolException, IOException {
        assertThat(response.getStatusLine().getStatusCode()).isEqualTo(responseCode);
        return null;
      }
    };
  }

  protected HttpClientContext getContext() {
    return getContextForAccount(admin);
  }

  protected HttpClientContext getUserContext() {
    return getContextForAccount(user);
  }

  protected HttpClientContext getAnonymousContext() {
    HttpClientContext ctx = HttpClientContext.create();
    return ctx;
  }

  private Project.NameKey createTestProject(String name) throws Exception {
    return projectOperations.newProject().name(name).parent(project).create();
  }

  private void setReplicationSource(
      String remoteName, String replicaSuffix, Optional<String> project) throws IOException {
    setReplicationSource(remoteName, Arrays.asList(replicaSuffix), project);
  }

  private void setReplicationSource(
      String remoteName, List<String> replicaSuffixes, Optional<String> project)
      throws IOException {

    List<String> replicaUrls =
        replicaSuffixes.stream()
            .map(suffix -> gitPath.resolve("${name}" + suffix + ".git").toString())
            .collect(toList());
    config.setString("replication", null, "instanceLabel", remoteName);
    config.setStringList("remote", remoteName, "url", replicaUrls);
    config.setString("remote", remoteName, "apiUrl", adminRestSession.url());
    config.setString("remote", remoteName, "fetch", "+refs/tags/*:refs/tags/*");
    config.setInt("remote", remoteName, "timeout", 600);
    config.setInt("remote", remoteName, "replicationDelay", TEST_REPLICATION_DELAY);
    project.ifPresent(prj -> config.setString("remote", remoteName, "projects", prj));
    config.setBoolean("gerrit", null, "autoReload", true);
    config.save();
  }

  private void setReplicationCredentials(String remoteName, String username, String password)
      throws IOException {
    secureConfig.setString("remote", remoteName, "username", username);
    secureConfig.setString("remote", remoteName, "password", password);
    secureConfig.save();
  }

  private HttpClientContext getContextForAccount(TestAccount account) {
    HttpClientContext ctx = HttpClientContext.create();
    CredentialsProvider adapted = new BasicCredentialsProvider();
    adapted.setCredentials(
        AuthScope.ANY, new UsernamePasswordCredentials(account.username(), account.httpPassword()));
    ctx.setCredentialsProvider(adapted);
    return ctx;
  }
}
