/*
 * Copyright 2014, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *
 *    * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.grpc.internal;

import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;

import io.grpc.InternalMetadata;
import io.grpc.Metadata;
import io.grpc.Status;

import java.nio.charset.Charset;

import javax.annotation.Nullable;

/**
 * Base implementation for client streams using HTTP2 as the transport.
 */
public abstract class Http2ClientStreamTransportState extends AbstractClientStream2.TransportState {

  /**
   * Metadata marshaller for HTTP status lines.
   */
  private static final InternalMetadata.TrustedAsciiMarshaller<Integer> HTTP_STATUS_MARSHALLER =
      new InternalMetadata.TrustedAsciiMarshaller<Integer>() {
        @Override
        public byte[] toAsciiString(Integer value) {
          throw new UnsupportedOperationException();
        }

        /**
         * RFC 7231 says status codes are 3 digits long.
         *
         * @see: <a href="https://tools.ietf.org/html/rfc7231#section-6">RFC 7231</a>
         */
        @Override
        public Integer parseAsciiString(byte[] serialized) {
          if (serialized.length >= 3) {
            return (serialized[0] - '0') * 100 + (serialized[1] - '0') * 10 + (serialized[2] - '0');
          }
          throw new NumberFormatException(
              "Malformed status code " + new String(serialized, InternalMetadata.US_ASCII));
        }
      };

  private static final Metadata.Key<Integer> HTTP2_STATUS = InternalMetadata.keyOf(":status",
      HTTP_STATUS_MARSHALLER);

  /** When non-{@code null}, {@link #transportErrorMetadata} must also be non-{@code null}. */
  private Status transportError;
  private Metadata transportErrorMetadata;
  private Charset errorCharset = Charsets.UTF_8;
  private boolean headersReceived;

  protected Http2ClientStreamTransportState(int maxMessageSize, StatsTraceContext statsTraceCtx) {
    super(maxMessageSize, statsTraceCtx);
  }

  /**
   * Called to process a failure in HTTP/2 processing. It should notify the transport to cancel the
   * stream and call {@code transportReportStatus()}.
   */
  protected abstract void http2ProcessingFailed(Status status, Metadata trailers);

  /**
   * Called by subclasses whenever {@code Headers} are received from the transport.
   *
   * @param headers the received headers
   */
  protected void transportHeadersReceived(Metadata headers) {
    Preconditions.checkNotNull(headers, "headers");
    if (transportError != null) {
      // Already received a transport error so just augment it. Something is really, really strange.
      transportError = transportError.augmentDescription("headers: " + headers);
      return;
    }
    try {
      if (headersReceived) {
        transportError = Status.INTERNAL.withDescription("Received headers twice");
        return;
      }
      Integer httpStatus = headers.get(HTTP2_STATUS);
      if (httpStatus != null && httpStatus >= 100 && httpStatus < 200) {
        // Ignore the headers. See RFC 7540 §8.1
        return;
      }
      headersReceived = true;

      transportError = validateInitialMetadata(headers);
      if (transportError != null) {
        return;
      }

      stripTransportDetails(headers);
      inboundHeadersReceived(headers);
    } finally {
      if (transportError != null) {
        // Note we don't immediately report the transport error, instead we wait for more data on
        // the stream so we can accumulate more detail into the error before reporting it.
        transportError = transportError.augmentDescription("headers: " + headers);
        transportErrorMetadata = headers;
        errorCharset = extractCharset(headers);
      }
    }
  }

  /**
   * Called by subclasses whenever a data frame is received from the transport.
   *
   * @param frame the received data frame
   * @param endOfStream {@code true} if there will be no more data received for this stream
   */
  protected void transportDataReceived(ReadableBuffer frame, boolean endOfStream) {
    if (transportError != null) {
      // We've already detected a transport error and now we're just accumulating more detail
      // for it.
      transportError = transportError.augmentDescription("DATA-----------------------------\n"
          + ReadableBuffers.readAsString(frame, errorCharset));
      frame.close();
      if (transportError.getDescription().length() > 1000 || endOfStream) {
        http2ProcessingFailed(transportError, transportErrorMetadata);
      }
    } else {
      inboundDataReceived(frame);
      if (endOfStream) {
        // This is a protocol violation as we expect to receive trailers.
        transportError =
            Status.INTERNAL.withDescription("Received unexpected EOS on DATA frame from server.");
        transportErrorMetadata = new Metadata();
        transportReportStatus(transportError, false, transportErrorMetadata);
      }
    }
  }

  /**
   * Called by subclasses for the terminal trailer metadata on a stream.
   *
   * @param trailers the received terminal trailer metadata
   */
  protected void transportTrailersReceived(Metadata trailers) {
    Preconditions.checkNotNull(trailers, "trailers");
    if (transportError == null && !headersReceived) {
      transportError = validateInitialMetadata(trailers);
      if (transportError != null) {
        transportErrorMetadata = trailers;
      }
    }
    if (transportError != null) {
      transportError = transportError.augmentDescription("trailers: " + trailers);
      http2ProcessingFailed(transportError, transportErrorMetadata);
    } else {
      Status status = statusFromTrailers(trailers);
      stripTransportDetails(trailers);
      inboundTrailersReceived(trailers, status);
    }
  }

  /**
   * Extract the response status from trailers.
   */
  private Status statusFromTrailers(Metadata trailers) {
    Status status = trailers.get(Status.CODE_KEY);
    if (status != null) {
      return status.withDescription(trailers.get(Status.MESSAGE_KEY));
    }
    // No status; something is broken. Try to provide a resonanable error.
    if (headersReceived) {
      return Status.UNKNOWN.withDescription("missing GRPC status in response");
    }
    Integer httpStatus = trailers.get(HTTP2_STATUS);
    if (httpStatus != null) {
      status = GrpcUtil.httpStatusToGrpcStatus(httpStatus);
    } else {
      status = Status.INTERNAL.withDescription("missing HTTP status code");
    }
    return status.augmentDescription(
        "missing GRPC status, inferred error from HTTP status code");
  }

  /**
   * Inspect initial headers to make sure they conform to HTTP and gRPC, returning a {@code Status}
   * on failure.
   *
   * @return status with description of failure, or {@code null} when valid
   */
  @Nullable
  private Status validateInitialMetadata(Metadata headers) {
    Integer httpStatus = headers.get(HTTP2_STATUS);
    if (httpStatus == null) {
      return Status.INTERNAL.withDescription("Missing HTTP status code");
    }
    String contentType = headers.get(GrpcUtil.CONTENT_TYPE_KEY);
    if (!GrpcUtil.isGrpcContentType(contentType)) {
      return GrpcUtil.httpStatusToGrpcStatus(httpStatus)
          .augmentDescription("invalid content-type: " + contentType);
    }
    return null;
  }

  /**
   * Inspect the raw metadata and figure out what charset is being used.
   */
  private static Charset extractCharset(Metadata headers) {
    String contentType = headers.get(GrpcUtil.CONTENT_TYPE_KEY);
    if (contentType != null) {
      String[] split = contentType.split("charset=");
      try {
        return Charset.forName(split[split.length - 1].trim());
      } catch (Exception t) {
        // Ignore and assume UTF-8
      }
    }
    return Charsets.UTF_8;
  }

  /**
   * Strip HTTP transport implementation details so they don't leak via metadata into
   * the application layer.
   */
  private static void stripTransportDetails(Metadata metadata) {
    metadata.discardAll(HTTP2_STATUS);
    metadata.discardAll(Status.CODE_KEY);
    metadata.discardAll(Status.MESSAGE_KEY);
  }
}
