// 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.entities.Project;
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.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();
    }
  }
}
