// 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.google.gerrit.plugins.checks.db;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Comparator.comparing;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.plugins.checks.Checker;
import com.google.gerrit.plugins.checks.CheckerRef;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.plugins.checks.Checkers;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;

/** Class to read checkers from NoteDb. */
@Singleton
class NoteDbCheckers implements Checkers {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final GitRepositoryManager repoManager;
  private final AllProjectsName allProjectsName;

  @Inject
  NoteDbCheckers(GitRepositoryManager repoManager, AllProjectsName allProjectsName) {
    this.repoManager = repoManager;
    this.allProjectsName = allProjectsName;
  }

  @Override
  public Optional<Checker> getChecker(CheckerUuid checkerUuid)
      throws IOException, ConfigInvalidException {
    try (Repository allProjectsRepo = repoManager.openRepository(allProjectsName)) {
      CheckerConfig checkerConfig =
          CheckerConfig.loadForChecker(allProjectsName, allProjectsRepo, checkerUuid);
      return checkerConfig.getLoadedChecker();
    }
  }

  @Override
  public ImmutableList<Checker> listCheckers() throws IOException {
    return listCheckers("");
  }

  @Override
  public ImmutableList<Checker> listCheckers(String scheme) throws IOException {
    if (scheme != null && !scheme.isEmpty() && !scheme.endsWith("/")) {
      scheme = scheme + "/";
    }
    try (Repository allProjectsRepo = repoManager.openRepository(allProjectsName)) {
      return allProjectsRepo.getRefDatabase().getRefsByPrefix(CheckerRef.REFS_CHECKERS + scheme)
          .stream()
          .flatMap(ref -> Streams.stream(tryLoadChecker(allProjectsRepo, ref)))
          .sorted(comparing(Checker::getUuid))
          .collect(toImmutableList());
    }
  }

  private Optional<Checker> tryLoadChecker(Repository allProjectsRepo, Ref ref) {
    if (CheckerRef.isRefsCheckers(ref.getName())) {
      try {
        return CheckerConfig.loadForChecker(allProjectsName, allProjectsRepo, ref)
            .getLoadedChecker();
      } catch (ConfigInvalidException | IOException e) {
        logger.atWarning().withCause(e).log(
            "Ignore invalid checker in %s while listing checkers", ref.getName());
      }
    }
    return Optional.empty();
  }

  @Override
  public ImmutableSortedSet<Checker> checkersOf(Project.NameKey repositoryName) throws IOException {
    try (Repository allProjectsRepo = repoManager.openRepository(allProjectsName)) {
      ImmutableSortedSet<CheckerUuid> checkerUuidStrings =
          CheckersByRepositoryNotes.load(allProjectsName, allProjectsRepo).get(repositoryName);
      ImmutableSortedSet.Builder<Checker> checkers =
          ImmutableSortedSet.orderedBy(comparing(Checker::getUuid));
      for (CheckerUuid checkerUuid : checkerUuidStrings) {
        try {
          CheckerConfig checkerConfig =
              CheckerConfig.loadForChecker(allProjectsName, allProjectsRepo, checkerUuid);
          checkerConfig.getLoadedChecker().ifPresent(checkers::add);
        } catch (ConfigInvalidException e) {
          logger.atWarning().withCause(e).log(
              "Ignore invalid checker %s on listing checkers for repository %s",
              checkerUuid, repositoryName);
        }
      }
      return checkers.build();
    }
  }
}
