// Copyright (C) 2019 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.healthcheck;

import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static com.google.common.truth.Truth.assertThat;
import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.ACTIVEWORKERS;
import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.AUTH;
import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.JGIT;
import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.QUERYCHANGES;

import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.Sandboxed;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.inject.Key;
import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames;
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.junit.Before;
import org.junit.Test;

@TestPlugin(
    name = "healthcheck-test",
    sysModule = "com.googlesource.gerrit.plugins.healthcheck.Module",
    httpModule = "com.googlesource.gerrit.plugins.healthcheck.HttpModule")
@Sandboxed
public class HealthCheckIT extends LightweightPluginDaemonTest {
  Gson gson = new Gson();
  HealthCheckConfig config;
  String healthCheckUriPath;

  @Override
  @Before
  public void setUpTestPlugin() throws Exception {
    super.setUpTestPlugin();

    config = plugin.getSysInjector().getInstance(HealthCheckConfig.class);
    int numChanges = config.getLimit(HealthCheckNames.QUERYCHANGES);
    for (int i = 0; i < numChanges; i++) {
      createChange("refs/for/master");
    }
    accountCreator.create(config.getUsername(HealthCheckNames.AUTH));

    healthCheckUriPath =
        String.format(
            "/config/server/%s~status",
            plugin.getSysInjector().getInstance(Key.get(String.class, PluginName.class)));
  }

  @Test
  public void shouldReturnOkWhenHealthy() throws Exception {
    getHealthCheckStatus().assertOK();
  }

  @Test
  public void shouldReturnAJsonPayload() throws Exception {
    assertThat(getHealthCheckStatus().getHeader(CONTENT_TYPE)).contains("application/json");
  }

  @Test
  public void shouldReturnJGitCheck() throws Exception {
    RestResponse resp = getHealthCheckStatus();

    resp.assertOK();
    assertCheckResult(getResponseJson(resp), JGIT, "passed");
  }

  @Test
  public void shouldReturnJGitCheckAsDisabled() throws Exception {
    disableCheck(JGIT);
    RestResponse resp = getHealthCheckStatus();

    resp.assertOK();
    assertCheckResult(getResponseJson(resp), JGIT, "disabled");
  }

  @Test
  @GerritConfig(name = "container.replica", value = "true")
  public void shouldReturnJGitCheckForReplicaWhenAuthenticated() throws Exception {
    RestResponse resp = getHealthCheckStatus();
    resp.assertOK();
    assertCheckResult(getResponseJson(resp), JGIT, "passed");
  }

  @Test
  @GerritConfig(name = "container.replica", value = "true")
  public void shouldReturnJGitCheckForReplicaAnonymously() throws Exception {
    RestResponse resp = getHealthCheckStatusAnonymously();
    resp.assertOK();
    assertCheckResult(getResponseJson(resp), JGIT, "passed");
  }

  @Test
  public void shouldReturnAuthCheck() throws Exception {
    RestResponse resp = getHealthCheckStatus();

    resp.assertOK();
    assertCheckResult(getResponseJson(resp), AUTH, "passed");
  }

  @Test
  public void shouldReturnAuthCheckAsDisabled() throws Exception {
    disableCheck(AUTH);
    RestResponse resp = getHealthCheckStatus();

    resp.assertOK();
    assertCheckResult(getResponseJson(resp), AUTH, "disabled");
  }

  @Test
  public void shouldReturnQueryChangesCheck() throws Exception {
    createChange("refs/for/master");
    RestResponse resp = getHealthCheckStatus();
    resp.assertOK();

    assertCheckResult(getResponseJson(resp), QUERYCHANGES, "passed");
  }

  @Test
  public void shouldReturnQueryChangesCheckAsDisabled() throws Exception {
    disableCheck(QUERYCHANGES);
    RestResponse resp = getHealthCheckStatus();

    resp.assertOK();
    assertCheckResult(getResponseJson(resp), QUERYCHANGES, "disabled");
  }

  @Test
  @GerritConfig(name = "container.replica", value = "true")
  public void shouldReturnQueryChangesAsDisabledForReplica() throws Exception {
    RestResponse resp = getHealthCheckStatus();
    resp.assertOK();

    assertCheckResult(getResponseJson(resp), QUERYCHANGES, "disabled");
  }

  @Test
  public void shouldReturnQueryChangesMultipleTimesCheck() throws Exception {
    createChange("refs/for/master");
    getHealthCheckStatus();
    RestResponse resp = getHealthCheckStatus();
    resp.assertOK();

    assertCheckResult(getResponseJson(resp), QUERYCHANGES, "passed");
  }

  @Test
  public void shouldReturnActiveWorkersCheck() throws Exception {
    createChange("refs/for/master");
    RestResponse resp = getHealthCheckStatus();
    resp.assertOK();

    assertCheckResult(getResponseJson(resp), ACTIVEWORKERS, "passed");
  }

  @Test
  public void shouldReturnActiveWorkersCheckAsDisabled() throws Exception {
    disableCheck(ACTIVEWORKERS);
    RestResponse resp = getHealthCheckStatus();

    resp.assertOK();
    assertCheckResult(getResponseJson(resp), ACTIVEWORKERS, "disabled");
  }

  @Test
  public void shouldReturnActiveWorkersMultipleTimesCheck() throws Exception {
    createChange("refs/for/master");
    getHealthCheckStatus();
    RestResponse resp = getHealthCheckStatus();
    resp.assertOK();

    assertCheckResult(getResponseJson(resp), ACTIVEWORKERS, "passed");
  }

  private RestResponse getHealthCheckStatus() throws IOException {
    return adminRestSession.get(healthCheckUriPath);
  }

  private RestResponse getHealthCheckStatusAnonymously() throws IOException {
    return anonymousRestSession.get(healthCheckUriPath);
  }

  private void assertCheckResult(JsonObject respPayload, String checkName, String result) {
    assertThat(respPayload.has(checkName)).isTrue();
    JsonObject reviewDbStatus = respPayload.get(checkName).getAsJsonObject();
    assertThat(reviewDbStatus.has("result")).isTrue();
    assertThat(reviewDbStatus.get("result").getAsString()).isEqualTo(result);
  }

  private void disableCheck(String check) throws ConfigInvalidException {
    config.fromText(String.format("[healthcheck \"%s\"]\n" + "enabled = false", check));
  }

  private JsonObject getResponseJson(RestResponse resp) throws IOException {
    JsonObject respPayload = gson.fromJson(resp.getReader(), JsonObject.class);
    return respPayload;
  }
}
