// Copyright (C) 2022 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.google.gerrit.server.git;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.gerrit.server.cache.PerThreadCache;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jgit.attributes.AttributesNodeProvider;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository.Builder;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectDatabase;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefRename;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.ReflogReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.util.FS;
import org.junit.Test;

public class RepoRefCacheTest {
  private static final String TEST_BRANCH = "main";

  @Test
  @SuppressWarnings("resource")
  public void repositoryUseShouldBeTrackedByRepoRefCache() throws Exception {
    RefCache cache;
    TestRepositoryWithRefCounting repoWithRefCounting;

    try (TestRepositoryWithRefCounting repo =
        TestRepositoryWithRefCounting.createWithBranch(TEST_BRANCH)) {
      assertThat(repo.refCounter()).isEqualTo(1);
      repoWithRefCounting = repo;
      cache = new RepoRefCache(repo);
    }

    assertThat(repoWithRefCounting.refCounter()).isEqualTo(1);
    assertThat(cache.get(Constants.R_HEADS + TEST_BRANCH)).isNotNull();
  }

  @Test
  @SuppressWarnings("resource")
  public void shouldNotKeepReferenceToReposWhenCacheIsFull() throws Exception {
    TestRepositoryWithRefCounting repoPointedFromCache;

    try (PerThreadCache threadCache = PerThreadCache.createReadOnly()) {
      fillUpAllThreadCache(threadCache);

      try (TestRepositoryWithRefCounting repo =
          TestRepositoryWithRefCounting.createWithBranch(TEST_BRANCH)) {
        repoPointedFromCache = repo;
        assertThat(repo.refCounter()).isEqualTo(1);
        Optional<RefCache> refCache = RepoRefCache.getOptional(repo);
        assertThat(refCache).isEqualTo(Optional.empty());
        assertThat(repo.refCounter()).isEqualTo(1);
      }

      assertThat(repoPointedFromCache.refCounter()).isEqualTo(0);
    }
  }

  @Test
  public void shouldCheckForStaleness() throws Exception {
    String refName = "refs/heads/foo";

    try (TestRepositoryWithRefCounting repo =
        TestRepositoryWithRefCounting.createWithBranch(TEST_BRANCH)) {
      RepoRefCache refCache = new RepoRefCache(repo);
      TestRepository<Repository> testRepo = new TestRepository<>(repo);

      Optional<ObjectId> cachedObjId = refCache.get(refName);

      assertThat(cachedObjId).isEqualTo(Optional.empty());

      RefUpdate refUpdate = repo.getRefDatabase().newUpdate(refName, true);
      refUpdate.setNewObjectId(testRepo.commit().create().getId());

      assertThat(refUpdate.forceUpdate()).isEqualTo(Result.NEW);

      IllegalStateException thrown =
          assertThrows(IllegalStateException.class, () -> refCache.checkStaleness());
      assertThat(thrown).hasMessageThat().contains(refName);
    }
  }

  private void fillUpAllThreadCache(PerThreadCache cache) {

    // Fill the cache
    for (int i = 0; i < 50; i++) {
      PerThreadCache.Key<String> key = PerThreadCache.Key.create(String.class, i);
      cache.getWithLoader(key, () -> "cached value", null);
    }
  }

  private static class TestRepositoryWithRefCounting extends Repository {
    private int refCounter;

    static TestRepositoryWithRefCounting createWithBranch(String branchName) throws Exception {
      Builder builder =
          new InMemoryRepository.Builder()
              .setRepositoryDescription(new DfsRepositoryDescription(""))
              .setFS(FS.detect().setUserHome(null));
      TestRepositoryWithRefCounting testRepo = new TestRepositoryWithRefCounting(builder);
      new TestRepository<>(testRepo).branch(branchName).commit().message("").create();
      return testRepo;
    }

    private final Repository repo;

    private TestRepositoryWithRefCounting(InMemoryRepository.Builder builder) throws IOException {
      super(builder);

      repo = builder.build();
      refCounter = 1;
    }

    public int refCounter() {
      return refCounter;
    }

    @Override
    public void incrementOpen() {
      repo.incrementOpen();
      refCounter++;
    }

    @Override
    public void close() {
      repo.close();
      refCounter--;
    }

    @Override
    public void create(boolean bare) throws IOException {}

    @Override
    public ObjectDatabase getObjectDatabase() {
      checkIsOpen();
      return repo.getObjectDatabase();
    }

    @Override
    public RefDatabase getRefDatabase() {
      RefDatabase refDatabase = repo.getRefDatabase();
      return new RefDatabase() {

        @Override
        public int hashCode() {
          return refDatabase.hashCode();
        }

        @Override
        public void create() throws IOException {
          refDatabase.create();
        }

        @Override
        public void close() {
          checkIsOpen();
          refDatabase.close();
        }

        @Override
        public boolean isNameConflicting(String name) throws IOException {
          checkIsOpen();
          return refDatabase.isNameConflicting(name);
        }

        @Override
        public boolean equals(Object obj) {
          return refDatabase.equals(obj);
        }

        @Override
        public Collection<String> getConflictingNames(String name) throws IOException {
          checkIsOpen();
          return refDatabase.getConflictingNames(name);
        }

        @Override
        public RefUpdate newUpdate(String name, boolean detach) throws IOException {
          checkIsOpen();
          return refDatabase.newUpdate(name, detach);
        }

        @Override
        public RefRename newRename(String fromName, String toName) throws IOException {
          checkIsOpen();
          return refDatabase.newRename(fromName, toName);
        }

        @Override
        public BatchRefUpdate newBatchUpdate() {
          checkIsOpen();
          return refDatabase.newBatchUpdate();
        }

        @Override
        public boolean performsAtomicTransactions() {
          checkIsOpen();
          return refDatabase.performsAtomicTransactions();
        }

        @Override
        public Ref getRef(String name) throws IOException {
          checkIsOpen();
          return refDatabase.getRef(name);
        }

        @Override
        public Ref exactRef(String name) throws IOException {
          checkIsOpen();
          return refDatabase.exactRef(name);
        }

        @Override
        public String toString() {
          return refDatabase.toString();
        }

        @Override
        public Map<String, Ref> exactRef(String... refs) throws IOException {
          checkIsOpen();
          return refDatabase.exactRef(refs);
        }

        @Override
        public Ref firstExactRef(String... refs) throws IOException {
          checkIsOpen();
          return refDatabase.firstExactRef(refs);
        }

        @Override
        public List<Ref> getRefs() throws IOException {
          checkIsOpen();
          return refDatabase.getRefs();
        }

        @Override
        public Map<String, Ref> getRefs(String prefix) throws IOException {
          checkIsOpen();
          return refDatabase.getRefs(prefix);
        }

        @Override
        public List<Ref> getRefsByPrefix(String prefix) throws IOException {
          checkIsOpen();
          return refDatabase.getRefsByPrefix(prefix);
        }

        @Override
        public boolean hasRefs() throws IOException {
          checkIsOpen();
          return refDatabase.hasRefs();
        }

        @Override
        public List<Ref> getAdditionalRefs() throws IOException {
          checkIsOpen();
          return refDatabase.getAdditionalRefs();
        }

        @Override
        public Ref peel(Ref ref) throws IOException {
          checkIsOpen();
          return refDatabase.peel(ref);
        }

        @Override
        public void refresh() {
          checkIsOpen();
          refDatabase.refresh();
        }
      };
    }

    @Override
    public StoredConfig getConfig() {
      return repo.getConfig();
    }

    @Override
    public AttributesNodeProvider createAttributesNodeProvider() {
      checkIsOpen();
      return repo.createAttributesNodeProvider();
    }

    @Override
    public void scanForRepoChanges() throws IOException {
      checkIsOpen();
    }

    @Override
    public void notifyIndexChanged(boolean internal) {
      checkIsOpen();
    }

    @Override
    public ReflogReader getReflogReader(String refName) throws IOException {
      checkIsOpen();
      return repo.getReflogReader(refName);
    }

    private void checkIsOpen() {
      if (refCounter <= 0) {
        throw new IllegalStateException("Repository is not open (refCounter=" + refCounter + ")");
      }
    }
  }
}
