// 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;

import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;

import com.google.auto.value.AutoValue;
import com.google.auto.value.extension.memoized.Memoized;
import com.google.common.base.Splitter;
import com.google.gerrit.common.UsedAt;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.logging.TraceContext;
import java.util.Optional;

/** Information about a request that was received from a user. */
@AutoValue
public abstract class RequestInfo {
  /** Channel through which a user request was received. */
  public enum RequestType {
    /** request type for git push */
    GIT_RECEIVE,

    /** request type for git fetch */
    GIT_UPLOAD,

    /** request type for call to REST API */
    REST,

    /** request type for call to SSH API */
    SSH
  }

  /**
   * Type of the request, telling through which channel the request was coming in.
   *
   * <p>See {@link RequestType} for the types that are used by Gerrit core. Other request types are
   * possible, e.g. if a plugin supports receiving requests through another channel.
   */
  public abstract String requestType();

  /**
   * Request URI.
   *
   * <p>Only set if request type is {@link RequestType#REST}.
   *
   * <p>Never includes the "/a" prefix.
   */
  public abstract Optional<String> requestUri();

  /**
   * Redacted request URI.
   *
   * <p>Request URI where resource IDs are replaced by '*'.
   */
  @Memoized
  public Optional<String> redactedRequestUri() {
    return requestUri().map(RequestInfo::redactRequestUri);
  }

  /** The user that has sent the request. */
  public abstract CurrentUser callingUser();

  /** The trace context of the request. */
  public abstract TraceContext traceContext();

  /**
   * The name of the project for which the request is being done. Only available if the request is
   * tied to a project or change. If a project is available it's not guaranteed that it actually
   * exists (e.g. if a user made a request for a project that doesn't exist).
   */
  public abstract Optional<Project.NameKey> project();

  @Memoized
  public String formatForLogging() {
    StringBuilder sb = new StringBuilder();
    sb.append(requestType());
    redactedRequestUri().ifPresent(redactedRequestUri -> sb.append(' ').append(redactedRequestUri));
    return sb.toString();
  }

  /**
   * Redacts resource IDs from the given request URI.
   *
   * <p>resource IDs in the request URI are replaced with '*'.
   *
   * @param requestUri a REST URI that has path segments that alternate between view name and
   *     resource IDs (e.g. "/<view>", "/<view>/<id>", "/<view>/<id>/<view>",
   *     "/<view>/<id>/<view>/<id>", "/<view>/<id>/<view>/<id>/<view>" etc.), must be given without
   *     the '/a' prefix
   * @return the redacted request URI
   */
  static String redactRequestUri(String requestUri) {
    requireNonNull(requestUri, "requestUri");
    checkState(
        !requestUri.startsWith("/a/"), "request URI must not start with '/a/': %s", requestUri);

    StringBuilder redactedRequestUri = new StringBuilder();

    boolean hasLeadingSlash = false;
    boolean hasTrailingSlash = false;
    if (requestUri.startsWith("/")) {
      hasLeadingSlash = true;
      requestUri = requestUri.substring(1);
    }
    if (requestUri.endsWith("/")) {
      hasTrailingSlash = true;
      requestUri = requestUri.substring(0, requestUri.length() - 1);
    }

    boolean idPathSegment = false;
    for (String pathSegment : Splitter.on('/').split(requestUri)) {
      if (!idPathSegment) {
        redactedRequestUri.append("/" + pathSegment);
        idPathSegment = true;
      } else {
        redactedRequestUri.append("/");
        if (!pathSegment.isEmpty()) {
          redactedRequestUri.append("*");
        }
        idPathSegment = false;
      }
    }

    if (!hasLeadingSlash) {
      redactedRequestUri.deleteCharAt(0);
    }
    if (hasTrailingSlash) {
      redactedRequestUri.append('/');
    }

    return redactedRequestUri.toString();
  }

  public static RequestInfo.Builder builder(
      RequestType requestType, CurrentUser callingUser, TraceContext traceContext) {
    return builder().requestType(requestType).callingUser(callingUser).traceContext(traceContext);
  }

  @UsedAt(UsedAt.Project.GOOGLE)
  public static RequestInfo.Builder builder() {
    return new AutoValue_RequestInfo.Builder();
  }

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder requestType(String requestType);

    public Builder requestType(RequestType requestType) {
      return requestType(requestType.name());
    }

    public abstract Builder requestUri(String requestUri);

    public abstract Builder callingUser(CurrentUser callingUser);

    public abstract Builder traceContext(TraceContext traceContext);

    public abstract Builder project(Project.NameKey projectName);

    public abstract RequestInfo build();
  }
}
