// Copyright 2019 Google LLC
//
// 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
//
//     https://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.gitiles;

import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_GONE;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;

import javax.annotation.Nullable;

/**
 * Indicates the request should be failed.
 *
 * <p>When an HTTP request should be failed, throw this exception instead of directly setting an
 * HTTP status code. The exception is caught by an error handler in {@link GitilesFilter}. By
 * default, {@link DefaultErrorHandlingFilter} handles this exception and set an appropriate HTTP
 * status code. If you want to customize how the error is surfaced, like changing the error page
 * rendering, replace this error handler from {@link GitilesServlet}.
 *
 * <h2>Extending the error space</h2>
 *
 * <p>{@link GitilesServlet} lets you customize some parts of Gitiles, and sometimes you would like
 * to create a new {@link FailureReason}. For example, a customized {@code RepositoryResolver} might
 * check a request quota and reject a request if a client sends too many requests. In that case, you
 * can define your own {@link RuntimeException} and an error handler.
 *
 * <pre><code>
 *   public final class MyRequestFailureException extends RuntimeException {
 *     private final FailureReason reason;
 *
 *     public MyRequestFailureException(FailureReason reason) {
 *       super();
 *       this.reason = reason;
 *     }
 *
 *     public FailureReason getReason() {
 *       return reason;
 *     }
 *
 *     enum FailureReason {
 *       QUOTA_EXCEEDED(429);
 *     }
 *
 *     private final int httpStatusCode;
 *
 *     FailureReason(int httpStatusCode) {
 *       this.httpStatusCode = httpStatusCode;
 *     }
 *
 *     public int getHttpStatusCode() {
 *       return httpStatusCode;
 *     }
 *   }
 *
 *   public class MyErrorHandlingFilter extends AbstractHttpFilter {
 *     private static final DefaultErrorHandlingFilter delegate =
 *         new DefaultErrorHandlingFilter();
 *
 *     {@literal @}Override
 *     public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
 *         throws IOException, ServletException {
 *       try {
 *         delegate.doFilter(req, res, chain);
 *       } catch (MyRequestFailureException e) {
 *         res.setHeader(DefaultErrorHandlingFilter.GITILES_ERROR, e.getReason().toString());
 *         res.sendError(e.getReason().getHttpStatusCode());
 *       }
 *     }
 *   }
 * </code></pre>
 *
 * <p>{@code RepositoryResolver} can throw {@code MyRequestFailureException} and {@code
 * MyErrorHandlingFilter} will handle that. You can control how the error should be surfaced.
 */
public final class GitilesRequestFailureException extends RuntimeException {
  private static final long serialVersionUID = 1L;
  private final FailureReason reason;
  private String publicErrorMessage;

  public GitilesRequestFailureException(FailureReason reason) {
    super();
    this.reason = reason;
  }

  public GitilesRequestFailureException(FailureReason reason, Throwable cause) {
    super(cause);
    this.reason = reason;
  }

  public GitilesRequestFailureException withPublicErrorMessage(String format, Object... params) {
    this.publicErrorMessage = String.format(format, params);
    return this;
  }

  public FailureReason getReason() {
    return reason;
  }

  @Nullable
  public String getPublicErrorMessage() {
    return publicErrorMessage;
  }

  /** The request failure reason. */
  public enum FailureReason {
    /** The object specified by the URL is ambiguous and Gitiles cannot identify one object. */
    AMBIGUOUS_OBJECT(SC_BAD_REQUEST),
    /** There's nothing to show for blame (e.g. the file is empty). */
    BLAME_REGION_NOT_FOUND(SC_NOT_FOUND),
    /** Cannot parse URL as a Gitiles URL. */
    CANNOT_PARSE_GITILES_VIEW(SC_NOT_FOUND),
    /** URL parameters are not valid. */
    INCORECT_PARAMETER(SC_BAD_REQUEST),
    /**
     * The object specified by the URL is not suitable for the view (e.g. trying to show a blob as a
     * tree).
     */
    INCORRECT_OBJECT_TYPE(SC_BAD_REQUEST),
    /** Markdown rendering is not enabled. */
    MARKDOWN_NOT_ENABLED(SC_NOT_FOUND),
    /** Request is not authorized. */
    NOT_AUTHORIZED(SC_UNAUTHORIZED),
    /** Object is not found. */
    OBJECT_NOT_FOUND(SC_NOT_FOUND),
    /** Object is too large to show. */
    OBJECT_TOO_LARGE(SC_INTERNAL_SERVER_ERROR),
    /** Repository is not found. */
    REPOSITORY_NOT_FOUND(SC_NOT_FOUND),
    /** Gitiles is not enabled for the repository. */
    SERVICE_NOT_ENABLED(SC_FORBIDDEN),
    /** GitWeb URL cannot be converted to Gitiles URL. */
    UNSUPPORTED_GITWEB_URL(SC_GONE),
    /** The specified object's type is not supported. */
    UNSUPPORTED_OBJECT_TYPE(SC_NOT_FOUND),
    /** The specified format type is not supported. */
    UNSUPPORTED_RESPONSE_FORMAT(SC_BAD_REQUEST),
    /** The specified revision names are not supported. */
    UNSUPPORTED_REVISION_NAMES(SC_BAD_REQUEST);

    private final int httpStatusCode;

    FailureReason(int httpStatusCode) {
      this.httpStatusCode = httpStatusCode;
    }

    public int getHttpStatusCode() {
      return httpStatusCode;
    }
  }
}
