// Copyright (C) 2019 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.logging;

import com.google.auto.value.AutoValue;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.LazyArg;
import com.google.common.flogger.LazyArgs;
import com.google.gerrit.common.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;

/** Metadata that is provided to {@link PerformanceLogger}s as context for performance records. */
@AutoValue
public abstract class Metadata {
  /** The numeric ID of an account. */
  public abstract Optional<Integer> accountId();

  /**
   * The type of an action (ACCOUNT_UPDATE, CHANGE_UPDATE, GROUP_UPDATE, INDEX_QUERY,
   * PLUGIN_UPDATE).
   */
  public abstract Optional<String> actionType();

  /** An authentication domain name. */
  public abstract Optional<String> authDomainName();

  /** The name of a branch. */
  public abstract Optional<String> branchName();

  /** Key of an entity in a cache. */
  public abstract Optional<String> cacheKey();

  /** The name of a cache. */
  public abstract Optional<String> cacheName();

  /** The name of the implementation class. */
  public abstract Optional<String> className();

  /**
   * The reason of a request cancellation (CLIENT_CLOSED_REQUEST, CLIENT_PROVIDED_DEADLINE_EXCEEDED,
   * SERVER_DEADLINE_EXCEEDED).
   */
  public abstract Optional<String> cancellationReason();

  /** The numeric ID of a change. */
  public abstract Optional<Integer> changeId();

  /**
   * The type of change ID which the user used to identify a change (e.g. numeric ID, triplet etc.).
   */
  public abstract Optional<String> changeIdType();

  /** The cause of an error. */
  public abstract Optional<String> cause();

  /** Side where the comment is written: <= 0 for parent, 1 for revision. */
  public abstract Optional<Integer> commentSide();

  /** The SHA1 of a commit. */
  public abstract Optional<String> commit();

  /** Diff algorithm used in diff computation. */
  public abstract Optional<String> diffAlgorithm();

  /** The type of an event. */
  public abstract Optional<String> eventType();

  /** The value of the @Export annotation which was used to register a plugin extension. */
  public abstract Optional<String> exportValue();

  /** Path of a file in a repository. */
  public abstract Optional<String> filePath();

  /** Garbage collector name. */
  public abstract Optional<String> garbageCollectorName();

  /** Git operation (CLONE, FETCH). */
  public abstract Optional<String> gitOperation();

  /** The numeric ID of an internal group. */
  public abstract Optional<Integer> groupId();

  /** The name of a group. */
  public abstract Optional<String> groupName();

  /** The UUID of a group. */
  public abstract Optional<String> groupUuid();

  /** HTTP status response code. */
  public abstract Optional<Integer> httpStatus();

  /** The name of a secondary index. */
  public abstract Optional<String> indexName();

  /** The version of a secondary index. */
  public abstract Optional<Integer> indexVersion();

  /** The name of the implementation method. */
  public abstract Optional<String> memoryPoolName();

  /** The name of the implementation method. */
  public abstract Optional<String> methodName();

  /** One or more resources */
  public abstract Optional<Boolean> multiple();

  /** The name of an operation that is performed. */
  public abstract Optional<String> operationName();

  /** Partial or full computation */
  public abstract Optional<Boolean> partial();

  /** If a value is still current or not */
  public abstract Optional<Boolean> outdated();

  /** Path of a metadata file in NoteDb. */
  public abstract Optional<String> noteDbFilePath();

  /** Name of a metadata ref in NoteDb. */
  public abstract Optional<String> noteDbRefName();

  /** Type of a sequence in NoteDb (ACCOUNTS, CHANGES, GROUPS). */
  public abstract Optional<String> noteDbSequenceType();

  /** The ID of a patch set. */
  public abstract Optional<Integer> patchSetId();

  /** Plugin metadata that doesn't fit into any other category. */
  public abstract ImmutableList<PluginMetadata> pluginMetadata();

  /** The name of a plugin. */
  public abstract Optional<String> pluginName();

  /** The name of a Gerrit project (aka Git repository). */
  public abstract Optional<String> projectName();

  /** The type of a Git push to Gerrit (CREATE_REPLACE, NORMAL, AUTOCLOSE). */
  public abstract Optional<String> pushType();

  /** The type of a Git push to Gerrit (GIT_RECEIVE, GIT_UPLOAD, REST, SSH). */
  public abstract Optional<String> requestType();

  /** The number of resources that is processed. */
  public abstract Optional<Integer> resourceCount();

  /** The name of a REST view. */
  public abstract Optional<String> restViewName();

  /** The SHA1 of Git commit. */
  public abstract Optional<String> revision();

  /** The username of an account. */
  public abstract Optional<String> username();

  /**
   * Returns a string representation of this instance that is suitable for logging. This is wrapped
   * in a {@link LazyArg} because it is expensive to evaluate.
   *
   * <p>{@link #toString()} formats the {@link Optional} fields as {@code key=Optional[value]} or
   * {@code key=Optional.empty}. Since this class has many optional fields from which usually only a
   * few are populated this leads to long string representations such as
   *
   * <pre>
   * Metadata{accountId=Optional.empty, actionType=Optional.empty, authDomainName=Optional.empty,
   * branchName=Optional.empty, cacheKey=Optional.empty, cacheName=Optional.empty,
   * className=Optional.empty, cancellationReason=Optional.empty changeId=Optional[9212550],
   * changeIdType=Optional.empty, cause=Optional.empty, diffAlgorithm=Optional.empty,
   * eventType=Optional.empty, exportValue=Optional.empty, filePath=Optional.empty,
   * garbageCollectorName=Optional.empty, gitOperation=Optional.empty, groupId=Optional.empty,
   * groupName=Optional.empty, groupUuid=Optional.empty, httpStatus=Optional.empty,
   * indexName=Optional.empty, indexVersion=Optional[0], methodName=Optional.empty,
   * multiple=Optional.empty, operationName=Optional.empty, partial=Optional.empty,
   * noteDbFilePath=Optional.empty, noteDbRefName=Optional.empty,
   * noteDbSequenceType=Optional.empty, patchSetId=Optional.empty, pluginMetadata=[],
   * pluginName=Optional.empty, projectName=Optional.empty, pushType=Optional.empty,
   * requestType=Optional.empty, resourceCount=Optional.empty, restViewName=Optional.empty,
   * revision=Optional.empty, username=Optional.empty}
   * </pre>
   *
   * <p>That's hard to read in logs. This is why this method
   *
   * <ul>
   *   <li>drops fields which have {@code Optional.empty} as value and
   *   <li>reformats values that are {@code Optional[value]} to {@code value}.
   * </ul>
   *
   * <p>For the example given above the formatted string would look like this:
   *
   * <pre>
   * Metadata{changeId=9212550, indexVersion=0, pluginMetadata=[]}
   * </pre>
   *
   * @return string representation of this instance that is suitable for logging
   */
  LazyArg<String> toStringForLoggingLazy() {
    // Don't use a lambda because different compilers generate different method names for lambdas,
    // e.g. "lambda$myFunction$0" vs. just "lambda$0" in Eclipse. We need to identify the method
    // by name to skip it and avoid infinite recursion.
    return LazyArgs.lazy(this::toStringForLoggingImpl);
  }

  private String toStringForLoggingImpl() {
    // Append class name.
    String className = getClass().getSimpleName();
    if (className.startsWith("AutoValue_")) {
      className = className.substring(10);
    }
    ToStringHelper stringHelper = MoreObjects.toStringHelper(className);

    // Append key-value pairs for field which are set.
    Method[] methods = Metadata.class.getDeclaredMethods();
    Arrays.sort(methods, Comparator.comparing(Method::getName));
    for (Method method : methods) {
      if (Modifier.isStatic(method.getModifiers())) {
        // skip static method
        continue;
      }

      if (method.getName().equals("toStringForLoggingLazy")
          || method.getName().equals("toStringForLoggingImpl")) {
        // Don't call myself in infinite recursion.
        continue;
      }

      if (method.getReturnType().equals(Void.TYPE) || method.getParameterCount() > 0) {
        // skip method since it's not a getter
        continue;
      }

      method.setAccessible(true);

      Object returnValue;
      try {
        returnValue = method.invoke(this);
      } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
        // should never happen
        throw new IllegalStateException(e);
      }

      if (returnValue instanceof Optional) {
        Optional<?> fieldValueOptional = (Optional<?>) returnValue;
        if (!fieldValueOptional.isPresent()) {
          // drop this key-value pair
          continue;
        }

        // format as 'key=value' instead of 'key=Optional[value]'
        stringHelper.add(method.getName(), fieldValueOptional.get());
      } else {
        // not an Optional value, keep as is
        stringHelper.add(method.getName(), returnValue);
      }
    }

    return stringHelper.toString();
  }

  public static Metadata.Builder builder() {
    return new AutoValue_Metadata.Builder();
  }

  public static Metadata empty() {
    return builder().build();
  }

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder accountId(int accountId);

    public abstract Builder actionType(@Nullable String actionType);

    public abstract Builder authDomainName(@Nullable String authDomainName);

    public abstract Builder branchName(@Nullable String branchName);

    public abstract Builder cacheKey(@Nullable String cacheKey);

    public abstract Builder cacheName(@Nullable String cacheName);

    public abstract Builder className(@Nullable String className);

    public abstract Builder cancellationReason(@Nullable String cancellationReason);

    public abstract Builder changeId(int changeId);

    public abstract Builder changeIdType(@Nullable String changeIdType);

    public abstract Builder cause(@Nullable String cause);

    public abstract Builder commentSide(int side);

    public abstract Builder commit(@Nullable String commit);

    public abstract Builder diffAlgorithm(@Nullable String diffAlgorithm);

    public abstract Builder eventType(@Nullable String eventType);

    public abstract Builder exportValue(@Nullable String exportValue);

    public abstract Builder filePath(@Nullable String filePath);

    public abstract Builder garbageCollectorName(@Nullable String garbageCollectorName);

    public abstract Builder gitOperation(@Nullable String gitOperation);

    public abstract Builder groupId(int groupId);

    public abstract Builder groupName(@Nullable String groupName);

    public abstract Builder groupUuid(@Nullable String groupUuid);

    public abstract Builder httpStatus(int httpStatus);

    public abstract Builder indexName(@Nullable String indexName);

    public abstract Builder indexVersion(int indexVersion);

    public abstract Builder memoryPoolName(@Nullable String memoryPoolName);

    public abstract Builder methodName(@Nullable String methodName);

    public abstract Builder multiple(boolean multiple);

    public abstract Builder operationName(String operationName);

    public abstract Builder partial(boolean partial);

    public abstract Builder outdated(boolean outdated);

    public abstract Builder noteDbFilePath(@Nullable String noteDbFilePath);

    public abstract Builder noteDbRefName(@Nullable String noteDbRefName);

    public abstract Builder noteDbSequenceType(@Nullable String noteDbSequenceType);

    public abstract Builder patchSetId(int patchSetId);

    abstract ImmutableList.Builder<PluginMetadata> pluginMetadataBuilder();

    public Builder addPluginMetadata(PluginMetadata pluginMetadata) {
      pluginMetadataBuilder().add(pluginMetadata);
      return this;
    }

    public abstract Builder pluginName(@Nullable String pluginName);

    public abstract Builder projectName(@Nullable String projectName);

    public abstract Builder pushType(@Nullable String pushType);

    public abstract Builder requestType(@Nullable String requestType);

    public abstract Builder resourceCount(int resourceCount);

    public abstract Builder restViewName(@Nullable String restViewName);

    public abstract Builder revision(@Nullable String revision);

    public abstract Builder username(@Nullable String username);

    public abstract Metadata build();
  }
}
