// 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 java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
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.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.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefRename;
import org.eclipse.jgit.lib.RefUpdate;
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();
  }

  private static class TestRepositoryWithRefCounting extends Repository {
    private int refCounter;

    @SuppressWarnings("resource")
    static TestRepositoryWithRefCounting createWithBranch(String branchName) throws Exception {
      InMemoryRepository.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 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
        @Deprecated
        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 + ")");
      }
    }

    @Override
    public String getIdentifier() {
      return "foo";
    }
  }
}
