// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/tools/flip_server/http_interface.h"

#include "net/tools/balsa/balsa_frame.h"
#include "net/tools/flip_server/flip_config.h"
#include "net/tools/flip_server/sm_connection.h"
#include "net/tools/flip_server/spdy_util.h"
#include "net/tools/flip_server/url_utilities.h"

namespace net {

HttpSM::HttpSM(SMConnection* connection,
               SMInterface* sm_spdy_interface,
               MemoryCache* memory_cache,
               FlipAcceptor* acceptor)
    : http_framer_(new BalsaFrame),
      stream_id_(0),
      server_idx_(-1),
      connection_(connection),
      sm_spdy_interface_(sm_spdy_interface),
      output_list_(connection->output_list()),
      output_ordering_(connection),
      memory_cache_(connection->memory_cache()),
      acceptor_(acceptor) {
  http_framer_->set_balsa_visitor(this);
  http_framer_->set_balsa_headers(&headers_);
  if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY)
    http_framer_->set_is_request(false);
}
HttpSM::~HttpSM() {
  Reset();
  delete http_framer_;
}

void HttpSM::ProcessBodyData(const char* input, size_t size) {
  if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
    VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process Body Data: stream "
            << stream_id_ << ": size " << size;
    sm_spdy_interface_->SendDataFrame(stream_id_, input, size, 0, false);
  }
}

void HttpSM::ProcessHeaders(const BalsaHeaders& headers) {
  if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) {
    std::string host =
        UrlUtilities::GetUrlHost(headers.GetHeader("Host").as_string());
    std::string method = headers.request_method().as_string();
    VLOG(1) << ACCEPTOR_CLIENT_IDENT
            << "Received Request: " << headers.request_uri().as_string() << " "
            << method;
    std::string filename =
        EncodeURL(headers.request_uri().as_string(), host, method);
    NewStream(stream_id_, 0, filename);
    stream_id_ += 2;
  } else {
    VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Received Response from "
            << connection_->server_ip_ << ":" << connection_->server_port_
            << " ";
    sm_spdy_interface_->SendSynReply(stream_id_, headers);
  }
}

void HttpSM::MessageDone() {
  if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
    VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone. Sending EOF: "
            << "stream " << stream_id_;
    sm_spdy_interface_->SendEOF(stream_id_);
  } else {
    VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: MessageDone.";
  }
}

void HttpSM::HandleHeaderError(BalsaFrame* framer) { HandleError(); }

void HttpSM::HandleChunkingError(BalsaFrame* framer) { HandleError(); }

void HttpSM::HandleBodyError(BalsaFrame* framer) { HandleError(); }

void HttpSM::HandleError() {
  VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Error detected";
}

void HttpSM::AddToOutputOrder(const MemCacheIter& mci) {
  output_ordering_.AddToOutputOrder(mci);
}

void HttpSM::InitSMInterface(SMInterface* sm_spdy_interface, int32 server_idx) {
  sm_spdy_interface_ = sm_spdy_interface;
  server_idx_ = server_idx;
}

void HttpSM::InitSMConnection(SMConnectionPoolInterface* connection_pool,
                              SMInterface* sm_interface,
                              EpollServer* epoll_server,
                              int fd,
                              std::string server_ip,
                              std::string server_port,
                              std::string remote_ip,
                              bool use_ssl) {
  VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Initializing server "
          << "connection.";
  connection_->InitSMConnection(connection_pool,
                                sm_interface,
                                epoll_server,
                                fd,
                                server_ip,
                                server_port,
                                remote_ip,
                                use_ssl);
}

size_t HttpSM::ProcessReadInput(const char* data, size_t len) {
  VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process read input: stream "
          << stream_id_;
  return http_framer_->ProcessInput(data, len);
}

size_t HttpSM::ProcessWriteInput(const char* data, size_t len) {
  VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Process write input: size "
          << len << ": stream " << stream_id_;
  char* dataPtr = new char[len];
  memcpy(dataPtr, data, len);
  DataFrame* data_frame = new DataFrame;
  data_frame->data = dataPtr;
  data_frame->size = len;
  data_frame->delete_when_done = true;
  connection_->EnqueueDataFrame(data_frame);
  return len;
}

bool HttpSM::MessageFullyRead() const {
  return http_framer_->MessageFullyRead();
}

void HttpSM::SetStreamID(uint32 stream_id) { stream_id_ = stream_id; }

bool HttpSM::Error() const { return http_framer_->Error(); }

const char* HttpSM::ErrorAsString() const {
  return BalsaFrameEnums::ErrorCodeToString(http_framer_->ErrorCode());
}

void HttpSM::Reset() {
  VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Reset: stream " << stream_id_;
  http_framer_->Reset();
}

void HttpSM::ResetForNewConnection() {
  if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
    VLOG(1) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Server connection closing "
            << "to: " << connection_->server_ip_ << ":"
            << connection_->server_port_ << " ";
  }
  // Message has not been fully read, either it is incomplete or the
  // server is closing the connection to signal message end.
  if (!MessageFullyRead()) {
    VLOG(2) << "HTTP response closed before end of file detected. "
            << "Sending EOF to spdy.";
    sm_spdy_interface_->SendEOF(stream_id_);
  }
  output_ordering_.Reset();
  http_framer_->Reset();
  if (sm_spdy_interface_) {
    sm_spdy_interface_->ResetForNewInterface(server_idx_);
  }
}

void HttpSM::Cleanup() {
  if (!(acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER)) {
    VLOG(2) << "HttpSM Request Fully Read; stream_id: " << stream_id_;
    connection_->Cleanup("request complete");
  }
}

int HttpSM::PostAcceptHook() { return 1; }

void HttpSM::NewStream(uint32 stream_id,
                       uint32 priority,
                       const std::string& filename) {
  MemCacheIter mci;
  mci.stream_id = stream_id;
  mci.priority = priority;
  if (!memory_cache_->AssignFileData(filename, &mci)) {
    // error creating new stream.
    VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending ErrorNotFound";
    SendErrorNotFound(stream_id);
  } else {
    AddToOutputOrder(mci);
  }
}

void HttpSM::SendEOF(uint32 stream_id) {
  SendEOFImpl(stream_id);
  if (acceptor_->flip_handler_type_ == FLIP_HANDLER_PROXY) {
    sm_spdy_interface_->ResetForNewInterface(server_idx_);
  }
}

void HttpSM::SendErrorNotFound(uint32 stream_id) {
  SendErrorNotFoundImpl(stream_id);
}

size_t HttpSM::SendSynStream(uint32 stream_id, const BalsaHeaders& headers) {
  return 0;
}

size_t HttpSM::SendSynReply(uint32 stream_id, const BalsaHeaders& headers) {
  return SendSynReplyImpl(stream_id, headers);
}

void HttpSM::SendDataFrame(uint32 stream_id,
                           const char* data,
                           int64 len,
                           uint32 flags,
                           bool compress) {
  SendDataFrameImpl(stream_id, data, len, flags, compress);
}

void HttpSM::SendEOFImpl(uint32 stream_id) {
  DataFrame* df = new DataFrame;
  df->data = "0\r\n\r\n";
  df->size = 5;
  df->delete_when_done = false;
  EnqueueDataFrame(df);
  if (acceptor_->flip_handler_type_ == FLIP_HANDLER_HTTP_SERVER) {
    Reset();
  }
}

void HttpSM::SendErrorNotFoundImpl(uint32 stream_id) {
  BalsaHeaders my_headers;
  my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "404", "Not Found");
  my_headers.RemoveAllOfHeader("content-length");
  my_headers.AppendHeader("transfer-encoding", "chunked");
  SendSynReplyImpl(stream_id, my_headers);
  SendDataFrame(stream_id, "page not found", 14, 0, false);
  SendEOFImpl(stream_id);
  output_ordering_.RemoveStreamId(stream_id);
}

size_t HttpSM::SendSynReplyImpl(uint32 stream_id, const BalsaHeaders& headers) {
  SimpleBuffer sb;
  headers.WriteHeaderAndEndingToBuffer(&sb);
  DataFrame* df = new DataFrame;
  df->size = sb.ReadableBytes();
  char* buffer = new char[df->size];
  df->data = buffer;
  df->delete_when_done = true;
  sb.Read(buffer, df->size);
  VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header "
          << stream_id_;
  size_t df_size = df->size;
  EnqueueDataFrame(df);
  return df_size;
}

size_t HttpSM::SendSynStreamImpl(uint32 stream_id,
                                 const BalsaHeaders& headers) {
  SimpleBuffer sb;
  headers.WriteHeaderAndEndingToBuffer(&sb);
  DataFrame* df = new DataFrame;
  df->size = sb.ReadableBytes();
  char* buffer = new char[df->size];
  df->data = buffer;
  df->delete_when_done = true;
  sb.Read(buffer, df->size);
  VLOG(2) << ACCEPTOR_CLIENT_IDENT << "Sending HTTP Reply header "
          << stream_id_;
  size_t df_size = df->size;
  EnqueueDataFrame(df);
  return df_size;
}

void HttpSM::SendDataFrameImpl(uint32 stream_id,
                               const char* data,
                               int64 len,
                               uint32 flags,
                               bool compress) {
  char chunk_buf[128];
  snprintf(chunk_buf, sizeof(chunk_buf), "%x\r\n", (unsigned int)len);
  std::string chunk_description(chunk_buf);
  DataFrame* df = new DataFrame;
  df->size = chunk_description.size() + len + 2;
  char* buffer = new char[df->size];
  df->data = buffer;
  df->delete_when_done = true;
  memcpy(buffer, chunk_description.data(), chunk_description.size());
  memcpy(buffer + chunk_description.size(), data, len);
  memcpy(buffer + chunk_description.size() + len, "\r\n", 2);
  EnqueueDataFrame(df);
}

void HttpSM::EnqueueDataFrame(DataFrame* df) {
  VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: Enqueue data frame: stream "
          << stream_id_;
  connection_->EnqueueDataFrame(df);
}

void HttpSM::GetOutput() {
  MemCacheIter* mci = output_ordering_.GetIter();
  if (mci == NULL) {
    VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput: nothing to "
            << "output!?: stream " << stream_id_;
    return;
  }
  if (!mci->transformed_header) {
    mci->bytes_sent =
        SendSynReply(mci->stream_id, *(mci->file_data->headers()));
    mci->transformed_header = true;
    VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput transformed "
            << "header stream_id: [" << mci->stream_id << "]";
    return;
  }
  if (mci->body_bytes_consumed >= mci->file_data->body().size()) {
    SendEOF(mci->stream_id);
    output_ordering_.RemoveStreamId(mci->stream_id);
    VLOG(2) << ACCEPTOR_CLIENT_IDENT << "GetOutput remove_stream_id: ["
            << mci->stream_id << "]";
    return;
  }
  size_t num_to_write =
      mci->file_data->body().size() - mci->body_bytes_consumed;
  if (num_to_write > mci->max_segment_size)
    num_to_write = mci->max_segment_size;

  SendDataFrame(mci->stream_id,
                mci->file_data->body().data() + mci->body_bytes_consumed,
                num_to_write,
                0,
                true);
  VLOG(2) << ACCEPTOR_CLIENT_IDENT << "HttpSM: GetOutput SendDataFrame["
          << mci->stream_id << "]: " << num_to_write;
  mci->body_bytes_consumed += num_to_write;
  mci->bytes_sent += num_to_write;
}

}  // namespace net
