// Copyright (C) 2020 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.codeowners.restapi;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableMap.toImmutableMap;

import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo.ConsistencyProblemInfo;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.plugins.codeowners.api.CheckCodeOwnerConfigFilesInRevisionInput;
import com.google.gerrit.plugins.codeowners.backend.ChangedFiles;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerBackend;
import com.google.gerrit.plugins.codeowners.backend.config.CodeOwnersPluginConfiguration;
import com.google.gerrit.plugins.codeowners.validation.CodeOwnerConfigValidator;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * REST endpoint that checks/validates the code owner config files in a revision.
 *
 * <p>This REST endpoint handles {@code POST
 * /changes/<change-id>/revisions/<revision-id>/code_owners.check_config} requests.
 */
@Singleton
public class CheckCodeOwnerConfigFilesInRevision
    implements RestModifyView<RevisionResource, CheckCodeOwnerConfigFilesInRevisionInput> {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final CodeOwnersPluginConfiguration codeOwnersPluginConfiguration;
  private final IdentifiedUser.GenericFactory genericUserFactory;
  private final GitRepositoryManager repoManager;
  private final ChangedFiles changedFiles;
  private final CodeOwnerConfigValidator codeOwnerConfigValidator;

  @Inject
  public CheckCodeOwnerConfigFilesInRevision(
      CodeOwnersPluginConfiguration codeOwnersPluginConfiguration,
      IdentifiedUser.GenericFactory genericUserFactory,
      GitRepositoryManager repoManager,
      ChangedFiles changedFiles,
      CodeOwnerConfigValidator codeOwnerConfigValidator) {
    this.codeOwnersPluginConfiguration = codeOwnersPluginConfiguration;
    this.genericUserFactory = genericUserFactory;
    this.repoManager = repoManager;
    this.changedFiles = changedFiles;
    this.codeOwnerConfigValidator = codeOwnerConfigValidator;
  }

  @Override
  public Response<Map<String, List<ConsistencyProblemInfo>>> apply(
      RevisionResource revisionResource, CheckCodeOwnerConfigFilesInRevisionInput input)
      throws IOException, PatchListNotAvailableException {
    logger.atFine().log(
        "checking code owner config files for revision %d of change %d (path = %s)",
        revisionResource.getPatchSet().number(),
        revisionResource.getChange().getChangeId(),
        input.path);

    CodeOwnerBackend codeOwnerBackend =
        codeOwnersPluginConfiguration.getBackend(revisionResource.getChange().getDest());

    IdentifiedUser uploader = genericUserFactory.create(revisionResource.getPatchSet().uploader());
    logger.atFine().log("uploader = %s", uploader.getLoggableName());

    try (Repository repository = repoManager.openRepository(revisionResource.getProject());
        RevWalk rw = new RevWalk(repository)) {
      RevCommit commit = rw.parseCommit(revisionResource.getPatchSet().commitId());
      return Response.ok(
          changedFiles.compute(revisionResource.getProject(), commit).stream()
              // filter out deletions (files without new path)
              .filter(changedFile -> changedFile.newPath().isPresent())
              // filter out non code owner config files
              .filter(
                  changedFile ->
                      codeOwnerBackend.isCodeOwnerConfigFile(
                          revisionResource.getProject(),
                          Paths.get(changedFile.newPath().get().toString())
                              .getFileName()
                              .toString()))
              .filter(
                  changedFile ->
                      input.path == null
                          || FileSystems.getDefault()
                              .getPathMatcher("glob:" + input.path)
                              .matches(changedFile.newPath().get()))
              .collect(
                  toImmutableMap(
                      changedFile -> changedFile.newPath().get().toString(),
                      changedFile ->
                          codeOwnerConfigValidator
                              .validateCodeOwnerConfig(
                                  uploader,
                                  codeOwnerBackend,
                                  revisionResource.getChange().getDest(),
                                  changedFile,
                                  rw,
                                  commit)
                              .map(
                                  commitValidationMessage ->
                                      CheckCodeOwnerConfigFiles.createConsistencyProblemInfo(
                                          commitValidationMessage, input.verbosity))
                              .filter(Optional::isPresent)
                              .map(Optional::get)
                              .collect(toImmutableList()))));
    }
  }
}
