// 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.modules.cache.chroniclemap;

import static com.google.common.truth.Truth.assertThat;
import static com.googlesource.gerrit.modules.cache.chroniclemap.AutoAdjustCachesCommand.CONFIG_HEADER;
import static com.googlesource.gerrit.modules.cache.chroniclemap.AutoAdjustCachesCommand.TUNED_INFIX;
import static com.googlesource.gerrit.modules.cache.chroniclemap.ChronicleMapCacheConfig.Defaults.maxBloatFactorFor;
import static com.googlesource.gerrit.modules.cache.chroniclemap.ChronicleMapCacheConfig.Defaults.maxEntriesFor;

import com.google.common.base.Joiner;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
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.UseLocalDisk;
import com.google.gerrit.acceptance.UseSsh;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.server.ModuleImpl;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import java.io.File;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;

@Sandboxed
@UseLocalDisk
@UseSsh
@TestPlugin(
    name = "cache-chroniclemap",
    sshModule = "com.googlesource.gerrit.modules.cache.chroniclemap.SSHCommandModule",
    httpModule = "com.googlesource.gerrit.modules.cache.chroniclemap.HttpModule")
public class AutoAdjustCachesIT extends LightweightPluginDaemonTest {
  private static final String SSH_CMD = "cache-chroniclemap auto-adjust-caches";
  private static final String REST_CMD = "/plugins/cache-chroniclemap/auto-adjust-caches";
  private static final String GROUPS_BYUUID_PERSISTED = "groups_byuuid_persisted";
  private static final String GERRIT_FILE_DIFF = "gerrit_file_diff";
  private static final String GIT_FILE_DIFF = "git_file_diff";
  private static final String DIFF_SUMMARY = "diff_summary";
  private static final String ACCOUNTS = "accounts";
  private static final String PERSISTED_PROJECTS = "persisted_projects";
  private static final String TEST_CACHE_NAME = "test_cache";
  private static final int TEST_CACHE_VERSION = 1;
  private static final String TEST_CACHE_FILENAME_TUNED =
      TEST_CACHE_NAME + "_" + TEST_CACHE_VERSION + AutoAdjustCaches.TUNED_INFIX;
  private static final String TEST_CACHE_KEY_100_CHARS = new String(new char[100]);
  private static final Function<String, Boolean> MATCH_ALL = (n) -> true;

  private static final ImmutableList<String> EXPECTED_CACHES =
      ImmutableList.of(
          GROUPS_BYUUID_PERSISTED,
          GERRIT_FILE_DIFF,
          GIT_FILE_DIFF,
          DIFF_SUMMARY,
          ACCOUNTS,
          PERSISTED_PROJECTS);

  @Inject private SitePaths sitePaths;

  @Inject
  @Named(TEST_CACHE_NAME)
  LoadingCache<String, String> testCache;

  @ModuleImpl(name = CacheModule.PERSISTENT_MODULE)
  public static class TestPersistentCacheModule extends CacheModule {

    @Override
    protected void configure() {
      persist(TEST_CACHE_NAME, String.class, String.class)
          .loader(TestCacheLoader.class)
          .version(TEST_CACHE_VERSION);
      install(new ChronicleMapCacheModule());
    }
  }

  public static class TestCacheLoader extends CacheLoader<String, String> {

    @Override
    public String load(String key) throws Exception {
      return key;
    }
  }

  @Override
  public com.google.inject.Module createModule() {
    return new TestPersistentCacheModule();
  }

  @Test
  public void shouldUseDefaultsWhenCachesAreNotConfigured() throws Exception {
    createChange();

    String result = adminSshSession.exec(SSH_CMD);

    adminSshSession.assertSuccess();
    Config configResult = configResult(result, CONFIG_HEADER);

    for (String cache : EXPECTED_CACHES) {
      assertThat(configResult.getLong("cache", cache, "maxEntries", 0))
          .isEqualTo(maxEntriesFor(cache));
      assertThat(configResult.getLong("cache", cache, "maxBloatFactor", 0))
          .isEqualTo(maxBloatFactorFor(cache));
    }
  }

  @Test
  public void shouldCreateNewCacheFiles() throws Exception {
    createChange();

    adminSshSession.exec(SSH_CMD);

    adminSshSession.assertSuccess();
    Set<String> tunedCaches =
        tunedFileNamesSet(n -> n.matches(".*(" + String.join("|", EXPECTED_CACHES) + ").*"));

    assertThat(tunedCaches.size()).isEqualTo(EXPECTED_CACHES.size());
  }

  @Test
  @GerritConfig(name = "cache.test_cache.avgKeySize", value = "207")
  @GerritConfig(name = "cache.test_cache.avgValueSize", value = "207")
  public void shouldNotRecreateTestCacheFileWhenAlreadyTuned() throws Exception {
    testCache.get(TEST_CACHE_KEY_100_CHARS);

    String tuneResult = adminSshSession.exec(SSH_CMD);
    adminSshSession.assertSuccess();

    assertThat(configResult(tuneResult, CONFIG_HEADER).getSubsections("cache"))
        .doesNotContain(TEST_CACHE_NAME);
    assertThat(Joiner.on('\n').join(tunedFileNamesSet(MATCH_ALL)))
        .doesNotContain(TEST_CACHE_FILENAME_TUNED);
  }

  @Test
  public void shouldCreateTestCacheTuned() throws Exception {
    testCache.get(TEST_CACHE_KEY_100_CHARS);
    String tuneResult = adminSshSession.exec(SSH_CMD);
    adminSshSession.assertSuccess();

    assertThat(configResult(tuneResult, CONFIG_HEADER).getSubsections("cache"))
        .contains(TEST_CACHE_NAME);
    assertThat(
            Joiner.on('\n').join(tunedFileNamesSet((n) -> n.contains(TEST_CACHE_FILENAME_TUNED))))
        .isNotEmpty();
  }

  @Test
  public void shouldDenyAccessOverSshToCreateNewCacheFiles() throws Exception {
    userSshSession.exec(SSH_CMD);
    userSshSession.assertFailure("not permitted");
  }

  @Test
  public void shouldDenyAccessOverRestToCreateNewCacheFiles() throws Exception {
    userRestSession.put(REST_CMD).assertForbidden();
  }

  @Test
  public void shouldAllowTuningOverRestForAdmin() throws Exception {
    RestResponse resp = adminRestSession.put(REST_CMD);

    resp.assertCreated();

    assertThat(configResult(resp.getEntityContent(), null).getSubsections("cache")).isNotEmpty();
    assertThat(tunedFileNamesSet(MATCH_ALL)).isNotEmpty();
  }

  private Config configResult(String result, @Nullable String configHeader)
      throws ConfigInvalidException {
    Config configResult = new Config();
    configResult.fromText(configHeader == null ? result : result.split(configHeader)[1]);
    return configResult;
  }

  private Set<String> tunedFileNamesSet(Function<String, Boolean> fileNameFilter) {
    Path cachePath = sitePaths.resolve(cfg.getString("cache", null, "directory"));
    return Stream.of(Objects.requireNonNull(cachePath.toFile().listFiles()))
        .filter(file -> !file.isDirectory())
        .map(File::getName)
        .filter(n -> n.contains(TUNED_INFIX) && fileNameFilter.apply(n))
        .collect(Collectors.toSet());
  }
}
