// Copyright (C) 2015 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;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;

import com.google.auto.value.AutoValue;
import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import com.google.common.primitives.Ints;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.index.change.ChangeIndexer;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;

@Singleton
public class StarredChangesUtil {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  @AutoValue
  public abstract static class StarField {
    private static final String SEPARATOR = ":";

    public static StarField parse(String s) {
      int p = s.indexOf(SEPARATOR);
      if (p >= 0) {
        Integer id = Ints.tryParse(s.substring(0, p));
        if (id == null) {
          return null;
        }
        Account.Id accountId = new Account.Id(id);
        String label = s.substring(p + 1);
        return create(accountId, label);
      }
      return null;
    }

    public static StarField create(Account.Id accountId, String label) {
      return new AutoValue_StarredChangesUtil_StarField(accountId, label);
    }

    public abstract Account.Id accountId();

    public abstract String label();

    @Override
    public String toString() {
      return accountId() + SEPARATOR + label();
    }
  }

  @AutoValue
  public abstract static class StarRef {
    private static final StarRef MISSING =
        new AutoValue_StarredChangesUtil_StarRef(null, ImmutableSortedSet.of());

    private static StarRef create(Ref ref, Iterable<String> labels) {
      return new AutoValue_StarredChangesUtil_StarRef(
          requireNonNull(ref), ImmutableSortedSet.copyOf(labels));
    }

    @Nullable
    public abstract Ref ref();

    public abstract ImmutableSortedSet<String> labels();

    public ObjectId objectId() {
      return ref() != null ? ref().getObjectId() : ObjectId.zeroId();
    }
  }

  public static class IllegalLabelException extends Exception {
    private static final long serialVersionUID = 1L;

    IllegalLabelException(String message) {
      super(message);
    }
  }

  public static class InvalidLabelsException extends IllegalLabelException {
    private static final long serialVersionUID = 1L;

    InvalidLabelsException(Set<String> invalidLabels) {
      super(String.format("invalid labels: %s", Joiner.on(", ").join(invalidLabels)));
    }
  }

  public static class MutuallyExclusiveLabelsException extends IllegalLabelException {
    private static final long serialVersionUID = 1L;

    MutuallyExclusiveLabelsException(String label1, String label2) {
      super(
          String.format(
              "The labels %s and %s are mutually exclusive. Only one of them can be set.",
              label1, label2));
    }
  }

  public static final String DEFAULT_LABEL = "star";
  public static final String IGNORE_LABEL = "ignore";
  public static final String REVIEWED_LABEL = "reviewed";
  public static final String UNREVIEWED_LABEL = "unreviewed";
  public static final ImmutableSortedSet<String> DEFAULT_LABELS =
      ImmutableSortedSet.of(DEFAULT_LABEL);

  private final GitRepositoryManager repoManager;
  private final GitReferenceUpdated gitRefUpdated;
  private final AllUsersName allUsers;
  private final Provider<PersonIdent> serverIdent;
  private final ChangeIndexer indexer;
  private final Provider<InternalChangeQuery> queryProvider;

  @Inject
  StarredChangesUtil(
      GitRepositoryManager repoManager,
      GitReferenceUpdated gitRefUpdated,
      AllUsersName allUsers,
      @GerritPersonIdent Provider<PersonIdent> serverIdent,
      ChangeIndexer indexer,
      Provider<InternalChangeQuery> queryProvider) {
    this.repoManager = repoManager;
    this.gitRefUpdated = gitRefUpdated;
    this.allUsers = allUsers;
    this.serverIdent = serverIdent;
    this.indexer = indexer;
    this.queryProvider = queryProvider;
  }

  public ImmutableSortedSet<String> getLabels(Account.Id accountId, Change.Id changeId)
      throws OrmException {
    try (Repository repo = repoManager.openRepository(allUsers)) {
      return readLabels(repo, RefNames.refsStarredChanges(changeId, accountId)).labels();
    } catch (IOException e) {
      throw new OrmException(
          String.format(
              "Reading stars from change %d for account %d failed",
              changeId.get(), accountId.get()),
          e);
    }
  }

  public ImmutableSortedSet<String> star(
      Account.Id accountId,
      Project.NameKey project,
      Change.Id changeId,
      Set<String> labelsToAdd,
      Set<String> labelsToRemove)
      throws OrmException, IllegalLabelException {
    try (Repository repo = repoManager.openRepository(allUsers)) {
      String refName = RefNames.refsStarredChanges(changeId, accountId);
      StarRef old = readLabels(repo, refName);

      Set<String> labels = new HashSet<>(old.labels());
      if (labelsToAdd != null) {
        labels.addAll(labelsToAdd);
      }
      if (labelsToRemove != null) {
        labels.removeAll(labelsToRemove);
      }

      if (labels.isEmpty()) {
        deleteRef(repo, refName, old.objectId());
      } else {
        checkMutuallyExclusiveLabels(labels);
        updateLabels(repo, refName, old.objectId(), labels);
      }

      indexer.index(project, changeId);
      return ImmutableSortedSet.copyOf(labels);
    } catch (IOException e) {
      throw new OrmException(
          String.format("Star change %d for account %d failed", changeId.get(), accountId.get()),
          e);
    }
  }

  public void unstarAll(Project.NameKey project, Change.Id changeId) throws OrmException {
    try (Repository repo = repoManager.openRepository(allUsers);
        RevWalk rw = new RevWalk(repo)) {
      BatchRefUpdate batchUpdate = repo.getRefDatabase().newBatchUpdate();
      batchUpdate.setAllowNonFastForwards(true);
      batchUpdate.setRefLogIdent(serverIdent.get());
      batchUpdate.setRefLogMessage("Unstar change " + changeId.get(), true);
      for (Account.Id accountId : byChangeFromIndex(changeId).keySet()) {
        String refName = RefNames.refsStarredChanges(changeId, accountId);
        Ref ref = repo.getRefDatabase().getRef(refName);
        batchUpdate.addCommand(new ReceiveCommand(ref.getObjectId(), ObjectId.zeroId(), refName));
      }
      batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
      for (ReceiveCommand command : batchUpdate.getCommands()) {
        if (command.getResult() != ReceiveCommand.Result.OK) {
          throw new IOException(
              String.format(
                  "Unstar change %d failed, ref %s could not be deleted: %s",
                  changeId.get(), command.getRefName(), command.getResult()));
        }
      }
      indexer.index(project, changeId);
    } catch (IOException e) {
      throw new OrmException(String.format("Unstar change %d failed", changeId.get()), e);
    }
  }

  public ImmutableMap<Account.Id, StarRef> byChange(Change.Id changeId) throws OrmException {
    try (Repository repo = repoManager.openRepository(allUsers)) {
      ImmutableMap.Builder<Account.Id, StarRef> builder = ImmutableMap.builder();
      for (String refPart : getRefNames(repo, RefNames.refsStarredChangesPrefix(changeId))) {
        Integer id = Ints.tryParse(refPart);
        if (id == null) {
          continue;
        }
        Account.Id accountId = new Account.Id(id);
        builder.put(accountId, readLabels(repo, RefNames.refsStarredChanges(changeId, accountId)));
      }
      return builder.build();
    } catch (IOException e) {
      throw new OrmException(
          String.format("Get accounts that starred change %d failed", changeId.get()), e);
    }
  }

  public ImmutableListMultimap<Account.Id, String> byChangeFromIndex(Change.Id changeId)
      throws OrmException {
    List<ChangeData> changeData =
        queryProvider
            .get()
            .setRequestedFields(ChangeField.ID, ChangeField.STAR)
            .byLegacyChangeId(changeId);
    if (changeData.size() != 1) {
      throw new NoSuchChangeException(changeId);
    }
    return changeData.get(0).stars();
  }

  private static Set<String> getRefNames(Repository repo, String prefix) throws IOException {
    RefDatabase refDb = repo.getRefDatabase();
    return refDb.getRefsByPrefix(prefix).stream()
        .map(r -> r.getName().substring(prefix.length()))
        .collect(toSet());
  }

  public ObjectId getObjectId(Account.Id accountId, Change.Id changeId) {
    try (Repository repo = repoManager.openRepository(allUsers)) {
      Ref ref = repo.exactRef(RefNames.refsStarredChanges(changeId, accountId));
      return ref != null ? ref.getObjectId() : ObjectId.zeroId();
    } catch (IOException e) {
      logger.atSevere().withCause(e).log(
          "Getting star object ID for account %d on change %d failed",
          accountId.get(), changeId.get());
      return ObjectId.zeroId();
    }
  }

  public void ignore(ChangeResource rsrc) throws OrmException, IllegalLabelException {
    star(
        rsrc.getUser().asIdentifiedUser().getAccountId(),
        rsrc.getProject(),
        rsrc.getChange().getId(),
        ImmutableSet.of(IGNORE_LABEL),
        ImmutableSet.of());
  }

  public void unignore(ChangeResource rsrc) throws OrmException, IllegalLabelException {
    star(
        rsrc.getUser().asIdentifiedUser().getAccountId(),
        rsrc.getProject(),
        rsrc.getChange().getId(),
        ImmutableSet.of(),
        ImmutableSet.of(IGNORE_LABEL));
  }

  public boolean isIgnoredBy(Change.Id changeId, Account.Id accountId) throws OrmException {
    return getLabels(accountId, changeId).contains(IGNORE_LABEL);
  }

  public boolean isIgnored(ChangeResource rsrc) throws OrmException {
    return isIgnoredBy(rsrc.getChange().getId(), rsrc.getUser().asIdentifiedUser().getAccountId());
  }

  private static String getReviewedLabel(Change change) {
    return getReviewedLabel(change.currentPatchSetId().get());
  }

  private static String getReviewedLabel(int ps) {
    return REVIEWED_LABEL + "/" + ps;
  }

  private static String getUnreviewedLabel(Change change) {
    return getUnreviewedLabel(change.currentPatchSetId().get());
  }

  private static String getUnreviewedLabel(int ps) {
    return UNREVIEWED_LABEL + "/" + ps;
  }

  public void markAsReviewed(ChangeResource rsrc) throws OrmException, IllegalLabelException {
    star(
        rsrc.getUser().asIdentifiedUser().getAccountId(),
        rsrc.getProject(),
        rsrc.getChange().getId(),
        ImmutableSet.of(getReviewedLabel(rsrc.getChange())),
        ImmutableSet.of(getUnreviewedLabel(rsrc.getChange())));
  }

  public void markAsUnreviewed(ChangeResource rsrc) throws OrmException, IllegalLabelException {
    star(
        rsrc.getUser().asIdentifiedUser().getAccountId(),
        rsrc.getProject(),
        rsrc.getChange().getId(),
        ImmutableSet.of(getUnreviewedLabel(rsrc.getChange())),
        ImmutableSet.of(getReviewedLabel(rsrc.getChange())));
  }

  public static StarRef readLabels(Repository repo, String refName) throws IOException {
    try (TraceTimer traceTimer = TraceContext.newTimer("Read star labels from %s", refName)) {
      Ref ref = repo.exactRef(refName);
      if (ref == null) {
        return StarRef.MISSING;
      }

      try (ObjectReader reader = repo.newObjectReader()) {
        ObjectLoader obj = reader.open(ref.getObjectId(), Constants.OBJ_BLOB);
        return StarRef.create(
            ref,
            Splitter.on(CharMatcher.whitespace())
                .omitEmptyStrings()
                .split(new String(obj.getCachedBytes(Integer.MAX_VALUE), UTF_8)));
      }
    }
  }

  public static ObjectId writeLabels(Repository repo, Collection<String> labels)
      throws IOException, InvalidLabelsException {
    validateLabels(labels);
    try (ObjectInserter oi = repo.newObjectInserter()) {
      ObjectId id =
          oi.insert(
              Constants.OBJ_BLOB,
              labels.stream().sorted().distinct().collect(joining("\n")).getBytes(UTF_8));
      oi.flush();
      return id;
    }
  }

  private static void checkMutuallyExclusiveLabels(Set<String> labels)
      throws MutuallyExclusiveLabelsException {
    if (labels.containsAll(ImmutableSet.of(DEFAULT_LABEL, IGNORE_LABEL))) {
      throw new MutuallyExclusiveLabelsException(DEFAULT_LABEL, IGNORE_LABEL);
    }

    Set<Integer> reviewedPatchSets = getStarredPatchSets(labels, REVIEWED_LABEL);
    Set<Integer> unreviewedPatchSets = getStarredPatchSets(labels, UNREVIEWED_LABEL);
    Optional<Integer> ps =
        Sets.intersection(reviewedPatchSets, unreviewedPatchSets).stream().findFirst();
    if (ps.isPresent()) {
      throw new MutuallyExclusiveLabelsException(
          getReviewedLabel(ps.get()), getUnreviewedLabel(ps.get()));
    }
  }

  public static Set<Integer> getStarredPatchSets(Set<String> labels, String label) {
    return labels.stream()
        .filter(l -> l.startsWith(label + "/"))
        .filter(l -> Ints.tryParse(l.substring(label.length() + 1)) != null)
        .map(l -> Integer.valueOf(l.substring(label.length() + 1)))
        .collect(toSet());
  }

  private static void validateLabels(Collection<String> labels) throws InvalidLabelsException {
    if (labels == null) {
      return;
    }

    SortedSet<String> invalidLabels = new TreeSet<>();
    for (String label : labels) {
      if (CharMatcher.whitespace().matchesAnyOf(label)) {
        invalidLabels.add(label);
      }
    }
    if (!invalidLabels.isEmpty()) {
      throw new InvalidLabelsException(invalidLabels);
    }
  }

  private void updateLabels(
      Repository repo, String refName, ObjectId oldObjectId, Collection<String> labels)
      throws IOException, OrmException, InvalidLabelsException {
    try (TraceTimer traceTimer =
            TraceContext.newTimer("Update star labels in %s (labels=%s)", refName, labels);
        RevWalk rw = new RevWalk(repo)) {
      RefUpdate u = repo.updateRef(refName);
      u.setExpectedOldObjectId(oldObjectId);
      u.setForceUpdate(true);
      u.setNewObjectId(writeLabels(repo, labels));
      u.setRefLogIdent(serverIdent.get());
      u.setRefLogMessage("Update star labels", true);
      RefUpdate.Result result = u.update(rw);
      switch (result) {
        case NEW:
        case FORCED:
        case NO_CHANGE:
        case FAST_FORWARD:
          gitRefUpdated.fire(allUsers, u, null);
          return;
        case IO_FAILURE:
        case LOCK_FAILURE:
        case NOT_ATTEMPTED:
        case REJECTED:
        case REJECTED_CURRENT_BRANCH:
        case RENAMED:
        case REJECTED_MISSING_OBJECT:
        case REJECTED_OTHER_REASON:
        default:
          throw new OrmException(
              String.format("Update star labels on ref %s failed: %s", refName, result.name()));
      }
    }
  }

  private void deleteRef(Repository repo, String refName, ObjectId oldObjectId)
      throws IOException, OrmException {
    if (ObjectId.zeroId().equals(oldObjectId)) {
      // ref doesn't exist
      return;
    }

    try (TraceTimer traceTimer = TraceContext.newTimer("Delete star labels in %s", refName)) {
      RefUpdate u = repo.updateRef(refName);
      u.setForceUpdate(true);
      u.setExpectedOldObjectId(oldObjectId);
      u.setRefLogIdent(serverIdent.get());
      u.setRefLogMessage("Unstar change", true);
      RefUpdate.Result result = u.delete();
      switch (result) {
        case FORCED:
          gitRefUpdated.fire(allUsers, u, null);
          return;
        case NEW:
        case NO_CHANGE:
        case FAST_FORWARD:
        case IO_FAILURE:
        case LOCK_FAILURE:
        case NOT_ATTEMPTED:
        case REJECTED:
        case REJECTED_CURRENT_BRANCH:
        case RENAMED:
        case REJECTED_MISSING_OBJECT:
        case REJECTED_OTHER_REASON:
        default:
          throw new OrmException(
              String.format("Delete star ref %s failed: %s", refName, result.name()));
      }
    }
  }
}
