// Copyright (C) 2023 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.update.context;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.UsedAt;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Optional;

/**
 * Passes additional information about an operation to the {@code BatchRefUpdate#execute} method.
 *
 * <p>To pass the additional information {@link RefUpdateContext}, wraps a code into an open
 * RefUpdateContext, e.g.:
 *
 * <pre>{@code
 * try(RefUpdateContext ctx = RefUpdateContext.open(RefUpdateType.CHANGE_MODIFICATION)) {
 *   ...
 *   // some code which modifies a ref using BatchRefUpdate.execute method
 * }
 * }</pre>
 *
 * When the {@code BatchRefUpdate#execute} method is executed, it can get all opened contexts and
 * use it for an additional actions, e.g. it can put it in the reflog.
 *
 * <p>The information provided by this class is used internally in google.
 *
 * <p>The InMemoryRepositoryManager file makes some validation to ensure that RefUpdateContext is
 * used correctly within the code (see thee validateRefUpdateContext method).
 *
 * <p>The class includes only operations from open-source gerrit and can be extended (see {@code
 * TestActionRefUpdateContext} for example how to extend it).
 */
public class RefUpdateContext implements AutoCloseable {
  private static final ThreadLocal<Deque<RefUpdateContext>> current = new ThreadLocal<>();

  /**
   * List of possible ref-update types.
   *
   * <p>Items in this enum are not fine-grained; different actions are shared the same type (e.g.
   * {@link #CHANGE_MODIFICATION} includes posting comments, change edits and attention set update).
   *
   * <p>It is expected, that each type of operation should include only specific ref(s); check the
   * validateRefUpdateContext in InMemoryRepositoryManager for relation between RefUpdateType and
   * ref name.
   */
  public enum RefUpdateType {
    /**
     * Indicates that the context is implemented as a descendant of the {@link RefUpdateContext} .
     *
     * <p>The {@link #getUpdateType()} returns this type for all descendant of {@link
     * RefUpdateContext}. This type is never returned if the context is exactly {@link
     * RefUpdateContext}.
     */
    OTHER,
    /**
     * A ref is updated as a part of change-related operation.
     *
     * <p>This covers multiple different cases - creating and uploading changes and patchsets,
     * comments operations, change edits, etc...
     */
    CHANGE_MODIFICATION,
    /** A ref is updated during merge-change operation. */
    MERGE_CHANGE,
    /** A ref is updated as a part of a repo sequence operation. */
    REPO_SEQ,
    /** A ref is updated as a part of a repo initialization. */
    INIT_REPO,
    /** A ref is udpated as a part of gpg keys modification. */
    GPG_KEYS_MODIFICATION,
    /** A ref is updated as a part of group(s) update */
    GROUPS_UPDATE,
    /** A ref is updated as a part of account(s) update. */
    ACCOUNTS_UPDATE,
    /** A ref is updated as a part of direct push. */
    DIRECT_PUSH,
    /** A ref is updated as a part of explicit branch or ref update operation. */
    BRANCH_MODIFICATION,
    /** A ref is updated as a part of explicit tag update operation. */
    TAG_MODIFICATION,
    /**
     * A tag is updated as a part of an offline operation.
     *
     * <p>Offline operation - an operation which is executed separately from the gerrit server and
     * can't be triggered by any gerrit API. E.g. schema update.
     */
    OFFLINE_OPERATION,
    /** A tag is updated as a part of an update-superproject flow. */
    UPDATE_SUPERPROJECT,
    /** A ref is updated as a part of explicit HEAD update operation. */
    HEAD_MODIFICATION,
    /** A ref is updated as a part of versioned meta data change. */
    VERSIONED_META_DATA_CHANGE,
    /** A ref is updated as a part of commit-ban operation. */
    BAN_COMMIT,
    /**
     * A ref is updated inside a plugin.
     *
     * <p>If a plugin updates one of a special refs - it must also open a nested context.
     */
    PLUGIN,
    /** A ref is updated as a part of auto-close-changes. */
    AUTO_CLOSE_CHANGES
  }

  /** Opens a provided context. */
  protected static <T extends RefUpdateContext> T open(T ctx) {
    getCurrent().addLast(ctx);
    return ctx;
  }

  /** Opens a context of a give type. */
  public static RefUpdateContext open(RefUpdateType updateType) {
    checkArgument(updateType != RefUpdateType.OTHER, "The OTHER type is for internal use only.");
    checkArgument(
        updateType != RefUpdateType.DIRECT_PUSH,
        "openDirectPush method with justification must be used to open DIRECT_PUSH context.");
    return open(new RefUpdateContext(updateType, Optional.empty()));
  }

  /** Opens a direct push context with an optional justification. */
  public static RefUpdateContext openDirectPush(Optional<String> justification) {
    return open(new RefUpdateContext(RefUpdateType.DIRECT_PUSH, justification));
  }

  /** Returns the list of opened contexts; the first element is the outermost context. */
  public static ImmutableList<RefUpdateContext> getOpenedContexts() {
    return ImmutableList.copyOf(getCurrent());
  }

  /** Checks if there is an open context of the given type. */
  public static boolean hasOpen(RefUpdateType type) {
    return getCurrent().stream().anyMatch(ctx -> ctx.getUpdateType() == type);
  }

  private final RefUpdateType updateType;
  private final Optional<String> justification;

  /**
   * Custom data, e.g. Google-specific data.
   *
   * <p>This data is only stored on the top-level context (on which nesting level custom data is
   * added is not relevant and storing it only on the top-level makes it easier to read custom data
   * as then it's not needed to iterate over all contexts to collect/merge all the custom data).
   */
  private List<Object> customData;

  private RefUpdateContext(RefUpdateType updateType, Optional<String> justification) {
    this.updateType = updateType;
    this.justification = justification;
  }

  protected RefUpdateContext(Optional<String> justification) {
    this(RefUpdateType.OTHER, justification);
  }

  protected static final Deque<RefUpdateContext> getCurrent() {
    Deque<RefUpdateContext> result = current.get();
    if (result == null) {
      result = new ArrayDeque<>();
      current.set(result);
    }
    return result;
  }

  /**
   * Add custom data.
   *
   * <p>Custom data is always stored on the top-level context, but can be added through any context.
   */
  @UsedAt(UsedAt.Project.GOOGLE)
  public void addCustomData(Object data) {
    // Store the data in the top-level context only.
    RefUpdateContext currentContext = current.get().getFirst();
    if (this != currentContext) {
      currentContext.addCustomData(data);
      return;
    }

    if (customData == null) {
      customData = new ArrayList<>();
    }
    customData.add(data);
  }

  /**
   * Get all custom data that has a type that is assignable from the given class.
   *
   * <p>Custom data is always stored on the top-level context, but can be retrieved through any
   * context.
   */
  @UsedAt(UsedAt.Project.GOOGLE)
  @SuppressWarnings("unchecked")
  public <T> ImmutableList<T> getCustomData(Class<T> clazz) {
    // The data is available in the top-level context only.
    RefUpdateContext currentContext = current.get().getFirst();
    if (this != currentContext) {
      return currentContext.getCustomData(clazz);
    }

    if (customData == null) {
      return ImmutableList.of();
    }

    return customData.stream()
        .filter(data -> clazz.isAssignableFrom(data.getClass()))
        .map(data -> (T) data)
        .collect(toImmutableList());
  }

  /**
   * Remove all custom data that has a type that is assignable from the given class.
   *
   * <p>Custom data is only stored on the top-level context, but clearing custom data can be done
   * through any context.
   */
  @UsedAt(UsedAt.Project.GOOGLE)
  public <T> void clearCustomData(Class<T> clazz) {
    // The data is available in the top-level context only.
    RefUpdateContext currentContext = current.get().getFirst();
    if (this != currentContext) {
      currentContext.clearCustomData(clazz);
      return;
    }

    if (customData == null) {
      return;
    }

    customData.removeAll(getCustomData(clazz));
  }

  /**
   * Returns the type of {@link RefUpdateContext}.
   *
   * <p>For descendants, always return {@link RefUpdateType#OTHER} (except known descendants defined
   * as nested classes).
   */
  public final RefUpdateType getUpdateType() {
    return updateType;
  }

  /** Returns the justification for the operation. */
  public final Optional<String> getJustification() {
    return justification;
  }

  /** Closes the current context. */
  @Override
  public void close() {
    Deque<RefUpdateContext> openedContexts = getCurrent();
    checkState(
        openedContexts.peekLast() == this, "The current context is different from this context.");
    openedContexts.removeLast();
  }
}
