// Copyright (C) 2016 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.notedb;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
import static com.google.gerrit.reviewdb.client.RefNames.refsDraftComments;
import static com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage.NOTE_DB;
import static com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage.REVIEW_DB;

import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.primitives.Longs;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
import com.google.gerrit.server.git.RefCache;
import com.google.gwtorm.server.OrmRuntimeException;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;

/**
 * The state of all relevant NoteDb refs across all repos corresponding to a given Change entity.
 *
 * <p>Stored serialized in the {@code Change#noteDbState} field, and used to determine whether the
 * state in NoteDb is out of date.
 *
 * <p>Serialized in one of the forms:
 *
 * <ul>
 *   <li>[meta-sha],[account1]=[drafts-sha],[account2]=[drafts-sha]...
 *   <li>R,[meta-sha],[account1]=[drafts-sha],[account2]=[drafts-sha]...
 *   <li>R=[read-only-until],[meta-sha],[account1]=[drafts-sha],[account2]=[drafts-sha]...
 *   <li>N
 *   <li>N=[read-only-until]
 * </ul>
 *
 * in numeric account ID order, with hex SHA-1s for human readability.
 */
public class NoteDbChangeState {
  public static final String NOTE_DB_PRIMARY_STATE = "N";

  public enum PrimaryStorage {
    REVIEW_DB('R'),
    NOTE_DB('N');

    private final char code;

    PrimaryStorage(char code) {
      this.code = code;
    }

    public static PrimaryStorage of(Change c) {
      return of(NoteDbChangeState.parse(c));
    }

    public static PrimaryStorage of(NoteDbChangeState s) {
      return s != null ? s.getPrimaryStorage() : REVIEW_DB;
    }
  }

  @AutoValue
  public abstract static class Delta {
    @VisibleForTesting
    public static Delta create(
        Change.Id changeId,
        Optional<ObjectId> newChangeMetaId,
        Map<Account.Id, ObjectId> newDraftIds) {
      if (newDraftIds == null) {
        newDraftIds = ImmutableMap.of();
      }
      return new AutoValue_NoteDbChangeState_Delta(
          changeId, newChangeMetaId, ImmutableMap.copyOf(newDraftIds));
    }

    abstract Change.Id changeId();

    abstract Optional<ObjectId> newChangeMetaId();

    abstract ImmutableMap<Account.Id, ObjectId> newDraftIds();
  }

  @AutoValue
  public abstract static class RefState {
    @VisibleForTesting
    public static RefState create(ObjectId changeMetaId, Map<Account.Id, ObjectId> draftIds) {
      return new AutoValue_NoteDbChangeState_RefState(
          changeMetaId.copy(),
          ImmutableMap.copyOf(Maps.filterValues(draftIds, id -> !ObjectId.zeroId().equals(id))));
    }

    private static Optional<RefState> parse(Change.Id changeId, List<String> parts) {
      checkArgument(!parts.isEmpty(), "missing state string for change %s", changeId);
      ObjectId changeMetaId = ObjectId.fromString(parts.get(0));
      Map<Account.Id, ObjectId> draftIds = Maps.newHashMapWithExpectedSize(parts.size() - 1);
      Splitter s = Splitter.on('=');
      for (int i = 1; i < parts.size(); i++) {
        String p = parts.get(i);
        List<String> draftParts = s.splitToList(p);
        checkArgument(
            draftParts.size() == 2, "invalid draft state part for change %s: %s", changeId, p);
        draftIds.put(Account.Id.parse(draftParts.get(0)), ObjectId.fromString(draftParts.get(1)));
      }
      return Optional.of(create(changeMetaId, draftIds));
    }

    abstract ObjectId changeMetaId();

    abstract ImmutableMap<Account.Id, ObjectId> draftIds();

    @Override
    public String toString() {
      return appendTo(new StringBuilder()).toString();
    }

    StringBuilder appendTo(StringBuilder sb) {
      sb.append(changeMetaId().name());
      for (Account.Id id : ReviewDbUtil.intKeyOrdering().sortedCopy(draftIds().keySet())) {
        sb.append(',').append(id.get()).append('=').append(draftIds().get(id).name());
      }
      return sb;
    }
  }

  public static NoteDbChangeState parse(Change c) {
    return c != null ? parse(c.getId(), c.getNoteDbState()) : null;
  }

  @VisibleForTesting
  public static NoteDbChangeState parse(Change.Id id, String str) {
    if (Strings.isNullOrEmpty(str)) {
      // Return null rather than Optional as this is what goes in the field in
      // ReviewDb.
      return null;
    }
    List<String> parts = Splitter.on(',').splitToList(str);
    String first = parts.get(0);
    Optional<Timestamp> readOnlyUntil = parseReadOnlyUntil(id, str, first);

    // Only valid NOTE_DB state is "N".
    if (parts.size() == 1 && first.charAt(0) == NOTE_DB.code) {
      return new NoteDbChangeState(id, NOTE_DB, Optional.empty(), readOnlyUntil);
    }

    // Otherwise it must be REVIEW_DB, either "R,<RefState>" or just
    // "<RefState>". Allow length > 0 for forward compatibility.
    if (first.length() > 0) {
      Optional<RefState> refState;
      if (first.charAt(0) == REVIEW_DB.code) {
        refState = RefState.parse(id, parts.subList(1, parts.size()));
      } else {
        refState = RefState.parse(id, parts);
      }
      return new NoteDbChangeState(id, REVIEW_DB, refState, readOnlyUntil);
    }
    throw invalidState(id, str);
  }

  private static Optional<Timestamp> parseReadOnlyUntil(
      Change.Id id, String fullStr, String first) {
    if (first.length() > 2 && first.charAt(1) == '=') {
      Long ts = Longs.tryParse(first.substring(2));
      if (ts == null) {
        throw invalidState(id, fullStr);
      }
      return Optional.of(new Timestamp(ts));
    }
    return Optional.empty();
  }

  private static IllegalArgumentException invalidState(Change.Id id, String str) {
    return new IllegalArgumentException("invalid state string for change " + id + ": " + str);
  }

  /**
   * Apply a delta to the state stored in a change entity.
   *
   * <p>This method does not check whether the old state was read-only; it is up to the caller to
   * not violate read-only semantics when storing the change back in ReviewDb.
   *
   * @param change change entity. The delta is applied against this entity's {@code noteDbState} and
   *     the new state is stored back in the entity as a side effect.
   * @param delta delta to apply.
   * @return new state, equivalent to what is stored in {@code change} as a side effect.
   */
  public static NoteDbChangeState applyDelta(Change change, Delta delta) {
    if (delta == null) {
      return null;
    }
    String oldStr = change.getNoteDbState();
    if (oldStr == null && !delta.newChangeMetaId().isPresent()) {
      // Neither an old nor a new meta ID was present, most likely because we
      // aren't writing a NoteDb graph at all for this change at this point. No
      // point in proceeding.
      return null;
    }
    NoteDbChangeState oldState = parse(change.getId(), oldStr);
    if (oldState != null && oldState.getPrimaryStorage() == NOTE_DB) {
      // NOTE_DB state doesn't include RefState, so applying a delta is a no-op.
      return oldState;
    }

    ObjectId changeMetaId;
    if (delta.newChangeMetaId().isPresent()) {
      changeMetaId = delta.newChangeMetaId().get();
      if (changeMetaId.equals(ObjectId.zeroId())) {
        change.setNoteDbState(null);
        return null;
      }
    } else {
      changeMetaId = oldState.getChangeMetaId();
    }

    Map<Account.Id, ObjectId> draftIds = new HashMap<>();
    if (oldState != null) {
      draftIds.putAll(oldState.getDraftIds());
    }
    for (Map.Entry<Account.Id, ObjectId> e : delta.newDraftIds().entrySet()) {
      if (e.getValue().equals(ObjectId.zeroId())) {
        draftIds.remove(e.getKey());
      } else {
        draftIds.put(e.getKey(), e.getValue());
      }
    }

    NoteDbChangeState state =
        new NoteDbChangeState(
            change.getId(),
            oldState != null ? oldState.getPrimaryStorage() : REVIEW_DB,
            Optional.of(RefState.create(changeMetaId, draftIds)),
            // Copy old read-only deadline rather than advancing it; the caller is
            // still responsible for finishing the rest of its work before the lease
            // runs out.
            oldState != null ? oldState.getReadOnlyUntil() : Optional.empty());
    change.setNoteDbState(state.toString());
    return state;
  }

  // TODO(dborowitz): Ugly. Refactor these static methods into a Checker class
  // or something. They do not belong in NoteDbChangeState itself because:
  //  - need to inject Config but don't want a whole Factory
  //  - can't be methods on NoteDbChangeState because state is nullable (though
  //    we could also solve this by inventing an empty-but-non-null state)
  // Also we should clean up duplicated code between static/non-static methods.
  public static boolean isChangeUpToDate(
      @Nullable NoteDbChangeState state, RefCache changeRepoRefs, Change.Id changeId)
      throws IOException {
    if (PrimaryStorage.of(state) == NOTE_DB) {
      return true; // Primary storage is NoteDb, up to date by definition.
    }
    if (state == null) {
      return !changeRepoRefs.get(changeMetaRef(changeId)).isPresent();
    }
    return state.isChangeUpToDate(changeRepoRefs);
  }

  public static boolean areDraftsUpToDate(
      @Nullable NoteDbChangeState state,
      RefCache draftsRepoRefs,
      Change.Id changeId,
      Account.Id accountId)
      throws IOException {
    if (PrimaryStorage.of(state) == NOTE_DB) {
      return true; // Primary storage is NoteDb, up to date by definition.
    }
    if (state == null) {
      return !draftsRepoRefs.get(refsDraftComments(changeId, accountId)).isPresent();
    }
    return state.areDraftsUpToDate(draftsRepoRefs, accountId);
  }

  public static long getReadOnlySkew(Config cfg) {
    return cfg.getTimeUnit("notedb", null, "maxTimestampSkew", 1000, TimeUnit.MILLISECONDS);
  }

  static Timestamp timeForReadOnlyCheck(long skewMs) {
    // Subtract some slop in case the machine that set the change's read-only
    // lease has a clock behind ours.
    return new Timestamp(TimeUtil.nowMs() - skewMs);
  }

  public static void checkNotReadOnly(@Nullable Change change, long skewMs) {
    checkNotReadOnly(parse(change), skewMs);
  }

  public static void checkNotReadOnly(@Nullable NoteDbChangeState state, long skewMs) {
    if (state == null) {
      return; // No state means ReviewDb primary non-read-only.
    } else if (state.isReadOnly(timeForReadOnlyCheck(skewMs))) {
      throw new OrmRuntimeException(
          "change "
              + state.getChangeId()
              + " is read-only until "
              + state.getReadOnlyUntil().get());
    }
  }

  private final Change.Id changeId;
  private final PrimaryStorage primaryStorage;
  private final Optional<RefState> refState;
  private final Optional<Timestamp> readOnlyUntil;

  public NoteDbChangeState(
      Change.Id changeId,
      PrimaryStorage primaryStorage,
      Optional<RefState> refState,
      Optional<Timestamp> readOnlyUntil) {
    this.changeId = checkNotNull(changeId);
    this.primaryStorage = checkNotNull(primaryStorage);
    this.refState = checkNotNull(refState);
    this.readOnlyUntil = checkNotNull(readOnlyUntil);

    switch (primaryStorage) {
      case REVIEW_DB:
        checkArgument(
            refState.isPresent(),
            "expected RefState for change %s with primary storage %s",
            changeId,
            primaryStorage);
        break;
      case NOTE_DB:
        checkArgument(
            !refState.isPresent(),
            "expected no RefState for change %s with primary storage %s",
            changeId,
            primaryStorage);
        break;
      default:
        throw new IllegalStateException("invalid PrimaryStorage: " + primaryStorage);
    }
  }

  public PrimaryStorage getPrimaryStorage() {
    return primaryStorage;
  }

  public boolean isChangeUpToDate(RefCache changeRepoRefs) throws IOException {
    if (primaryStorage == NOTE_DB) {
      return true; // Primary storage is NoteDb, up to date by definition.
    }
    Optional<ObjectId> id = changeRepoRefs.get(changeMetaRef(changeId));
    if (!id.isPresent()) {
      return getChangeMetaId().equals(ObjectId.zeroId());
    }
    return id.get().equals(getChangeMetaId());
  }

  public boolean areDraftsUpToDate(RefCache draftsRepoRefs, Account.Id accountId)
      throws IOException {
    if (primaryStorage == NOTE_DB) {
      return true; // Primary storage is NoteDb, up to date by definition.
    }
    Optional<ObjectId> id = draftsRepoRefs.get(refsDraftComments(changeId, accountId));
    if (!id.isPresent()) {
      return !getDraftIds().containsKey(accountId);
    }
    return id.get().equals(getDraftIds().get(accountId));
  }

  public boolean isUpToDate(RefCache changeRepoRefs, RefCache draftsRepoRefs) throws IOException {
    if (primaryStorage == NOTE_DB) {
      return true; // Primary storage is NoteDb, up to date by definition.
    }
    if (!isChangeUpToDate(changeRepoRefs)) {
      return false;
    }
    for (Account.Id accountId : getDraftIds().keySet()) {
      if (!areDraftsUpToDate(draftsRepoRefs, accountId)) {
        return false;
      }
    }
    return true;
  }

  public boolean isReadOnly(Timestamp now) {
    return readOnlyUntil.isPresent() && now.before(readOnlyUntil.get());
  }

  public Optional<Timestamp> getReadOnlyUntil() {
    return readOnlyUntil;
  }

  public NoteDbChangeState withReadOnlyUntil(Timestamp ts) {
    return new NoteDbChangeState(changeId, primaryStorage, refState, Optional.of(ts));
  }

  public Change.Id getChangeId() {
    return changeId;
  }

  public ObjectId getChangeMetaId() {
    return refState().changeMetaId();
  }

  public ImmutableMap<Account.Id, ObjectId> getDraftIds() {
    return refState().draftIds();
  }

  public Optional<RefState> getRefState() {
    return refState;
  }

  private RefState refState() {
    checkState(refState.isPresent(), "state for %s has no RefState: %s", changeId, this);
    return refState.get();
  }

  @Override
  public String toString() {
    switch (primaryStorage) {
      case REVIEW_DB:
        if (!readOnlyUntil.isPresent()) {
          // Don't include enum field, just IDs (though parse would accept it).
          return refState().toString();
        }
        return primaryStorage.code + "=" + readOnlyUntil.get().getTime() + "," + refState.get();
      case NOTE_DB:
        if (!readOnlyUntil.isPresent()) {
          return NOTE_DB_PRIMARY_STATE;
        }
        return primaryStorage.code + "=" + readOnlyUntil.get().getTime();
      default:
        throw new IllegalArgumentException("Unsupported PrimaryStorage: " + primaryStorage);
    }
  }

  @Override
  public int hashCode() {
    return Objects.hash(changeId, primaryStorage, refState, readOnlyUntil);
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof NoteDbChangeState)) {
      return false;
    }
    NoteDbChangeState s = (NoteDbChangeState) o;
    return changeId.equals(s.changeId)
        && primaryStorage.equals(s.primaryStorage)
        && refState.equals(s.refState)
        && readOnlyUntil.equals(s.readOnlyUntil);
  }
}
