// Copyright (C) 2013 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.query.change;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.gerrit.server.project.ProjectCache.noSuchProject;
import static java.util.concurrent.TimeUnit.MINUTES;

import com.google.common.flogger.FluentLogger;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.SubmitTypeRecord;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.index.query.PostFilterPredicate;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeQueryBuilder.Arguments;
import com.google.gerrit.server.submit.SubmitDryRun;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

public class ConflictsPredicate {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  // UI code may depend on this string, so use caution when changing.
  protected static final String TOO_MANY_FILES = "too many files to find conflicts";

  private ConflictsPredicate() {}

  public static Predicate<ChangeData> create(Arguments args, String value, Change c)
      throws QueryParseException {
    ChangeData cd;
    List<String> files;
    try {
      cd = args.changeDataFactory.create(c);
      files = cd.currentFilePaths();
    } catch (StorageException e) {
      warnWithOccasionalStackTrace(
          e,
          "Error constructing conflicts predicates for change %s in %s",
          c.getId(),
          c.getProject());
      return ChangeIndexPredicate.none();
    }

    if (3 + files.size() > args.indexConfig.maxTerms()) {
      // Short-circuit with a nice error message if we exceed the index
      // backend's term limit. This assumes that "conflicts:foo" is the entire
      // query; if there are more terms in the input, we might not
      // short-circuit here, which will result in a more generic error message
      // later on in the query parsing.
      throw new QueryParseException(TOO_MANY_FILES);
    }

    List<Predicate<ChangeData>> filePredicates = new ArrayList<>(files.size());
    for (String file : files) {
      filePredicates.add(ChangePredicates.path(file));
    }

    List<Predicate<ChangeData>> and = new ArrayList<>(5);
    and.add(ChangePredicates.project(c.getProject()));
    and.add(ChangePredicates.ref(c.getDest().branch()));
    and.add(Predicate.not(ChangePredicates.changeNumber(c.getId(), args)));
    and.add(Predicate.or(filePredicates));

    ChangeDataCache changeDataCache = new ChangeDataCache(cd, args.projectCache);
    and.add(new CheckConflict(value, args, c, changeDataCache));
    return Predicate.and(and);
  }

  private static final class CheckConflict extends PostFilterPredicate<ChangeData> {
    private final Arguments args;
    private final BranchNameKey dest;
    private final ChangeDataCache changeDataCache;

    CheckConflict(String value, Arguments args, Change c, ChangeDataCache changeDataCache) {
      super(ChangeQueryBuilder.FIELD_CONFLICTS, value);
      this.args = args;
      this.dest = c.getDest();
      this.changeDataCache = changeDataCache;
    }

    @Override
    public boolean match(ChangeData object) {
      Change.Id id = object.getId();
      Project.NameKey otherProject = null;
      ObjectId other = null;
      try {
        Change otherChange = object.change();
        if (otherChange == null || !otherChange.getDest().equals(dest)) {
          return false;
        }
        otherProject = otherChange.getProject();

        SubmitTypeRecord str = object.submitTypeRecord();
        if (!str.isOk()) {
          return false;
        }

        ProjectState projectState;
        try {
          projectState = changeDataCache.getProjectState();
        } catch (NoSuchProjectException e) {
          return false;
        }

        other = object.currentPatchSet().commitId();
        ConflictKey conflictsKey =
            ConflictKey.create(
                changeDataCache.getTestAgainst(),
                other,
                str.type,
                projectState.is(BooleanProjectConfig.USE_CONTENT_MERGE));
        return args.conflictsCache.get(conflictsKey, new Loader(object, changeDataCache, args));
      } catch (StorageException | ExecutionException | UncheckedExecutionException e) {
        ObjectId finalOther = other;
        warnWithOccasionalStackTrace(
            e,
            "Merge failure checking conflicts of change %s in %s (%s): %s",
            id,
            firstNonNull(otherProject, "unknown project"),
            finalOther != null ? finalOther.name() : "unknown commit",
            e.getMessage());
        return false;
      }
    }

    @Override
    public int getCost() {
      return 5;
    }
  }

  static class ChangeDataCache {
    private final ChangeData cd;
    private final ProjectCache projectCache;

    private ObjectId testAgainst;
    private ProjectState projectState;
    private Set<ObjectId> alreadyAccepted;

    ChangeDataCache(ChangeData cd, ProjectCache projectCache) {
      this.cd = cd;
      this.projectCache = projectCache;
    }

    ObjectId getTestAgainst() {
      if (testAgainst == null) {
        testAgainst = cd.currentPatchSet().commitId();
      }
      return testAgainst;
    }

    ProjectState getProjectState() throws NoSuchProjectException {
      if (projectState == null) {
        projectState = projectCache.get(cd.project()).orElseThrow(noSuchProject(cd.project()));
      }
      return projectState;
    }

    Set<ObjectId> getAlreadyAccepted(Repository repo) throws IOException {
      if (alreadyAccepted == null) {
        alreadyAccepted = SubmitDryRun.getAlreadyAccepted(repo);
      }
      return alreadyAccepted;
    }
  }

  private static void warnWithOccasionalStackTrace(Throwable cause, String format, Object... args) {
    logger.atWarning().logVarargs(format, args);
    logger
        .atWarning()
        .withCause(cause)
        .atMostEvery(1, MINUTES)
        .logVarargs("(Re-logging with stack trace) " + format, args);
  }

  private static class Loader implements Callable<Boolean> {
    private final ChangeData changeData;
    private final ConflictsPredicate.ChangeDataCache changeDataCache;
    private final ChangeQueryBuilder.Arguments args;

    private Loader(
        ChangeData changeData,
        ConflictsPredicate.ChangeDataCache changeDataCache,
        ChangeQueryBuilder.Arguments args) {
      this.changeData = changeData;
      this.changeDataCache = changeDataCache;
      this.args = args;
    }

    @Override
    public Boolean call() throws Exception {
      Change otherChange = changeData.change();
      ObjectId other = changeData.currentPatchSet().commitId();
      try (Repository repo = args.repoManager.openRepository(otherChange.getProject());
          CodeReviewCommit.CodeReviewRevWalk rw = CodeReviewCommit.newRevWalk(repo)) {
        return !args.submitDryRun.run(
            null,
            changeData.submitTypeRecord().type,
            repo,
            rw,
            otherChange.getDest(),
            changeDataCache.getTestAgainst(),
            other,
            getAlreadyAccepted(repo, rw));
      } catch (NoSuchProjectException | IOException e) {
        warnWithOccasionalStackTrace(
            e,
            "Failure when loading conflicts of change %s in %s (%s): %s",
            changeData.getId(),
            firstNonNull(otherChange.getProject(), "unknown project"),
            other != null ? other.name() : "unknown commit",
            e.getMessage());
        return false;
      }
    }

    private Set<RevCommit> getAlreadyAccepted(Repository repo, RevWalk rw) {
      try {
        Set<RevCommit> accepted = new HashSet<>();
        SubmitDryRun.addCommits(changeDataCache.getAlreadyAccepted(repo), rw, accepted);
        ObjectId tip = changeDataCache.getTestAgainst();
        if (tip != null) {
          accepted.add(rw.parseCommit(tip));
        }
        return accepted;
      } catch (StorageException | IOException e) {
        throw new StorageException("Failed to determine already accepted commits.", e);
      }
    }
  }
}
