// 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/dump_cache/url_utilities.h"
#include "net/tools/flip_server/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"

namespace net {

HttpSM::HttpSM(SMConnection* connection,
               SMInterface* sm_spdy_interface,
               EpollServer* epoll_server,
               MemoryCache* memory_cache,
               FlipAcceptor* acceptor)
    : seq_num_(0),
      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::SendOKResponse(uint32 stream_id, std::string* output) {
  SendOKResponseImpl(stream_id, output);
}

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 = (const char *)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_);
  }
  seq_num_ = 0;
  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);
}

void HttpSM::SendOKResponseImpl(uint32 stream_id, std::string* output) {
  BalsaHeaders my_headers;
  my_headers.SetFirstlineFromStringPieces("HTTP/1.1", "200", "OK");
  my_headers.RemoveAllOfHeader("content-length");
  my_headers.AppendHeader("transfer-encoding", "chunked");
  SendSynReplyImpl(stream_id, my_headers);
  SendDataFrame(stream_id, output->c_str(), output->size(), 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
