// Copyright (c) 2012 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/test/embedded_test_server/http_connection.h"

#include <utility>

#include "net/base/net_errors.h"
#include "net/socket/stream_socket.h"

namespace net {
namespace test_server {

HttpConnection::HttpConnection(scoped_ptr<StreamSocket> socket,
                               const HandleRequestCallback& callback)
    : socket_(std::move(socket)),
      callback_(callback),
      read_buf_(new IOBufferWithSize(4096)),
      weak_factory_(this) {}

HttpConnection::~HttpConnection() {
  weak_factory_.InvalidateWeakPtrs();
}

void HttpConnection::SendResponseBytes(const std::string& response_string,
                                       const SendCompleteCallback& callback) {
  if (response_string.length() > 0) {
    scoped_refptr<DrainableIOBuffer> write_buf(new DrainableIOBuffer(
        new StringIOBuffer(response_string), response_string.length()));

    SendInternal(callback, write_buf);
  } else {
    callback.Run();
  }
}

int HttpConnection::ReadData(const CompletionCallback& callback) {
  return socket_->Read(read_buf_.get(), read_buf_->size(), callback);
}

bool HttpConnection::ConsumeData(int size) {
  request_parser_.ProcessChunk(base::StringPiece(read_buf_->data(), size));
  if (request_parser_.ParseRequest() == HttpRequestParser::ACCEPTED) {
    callback_.Run(this, request_parser_.GetRequest());
    return true;
  }
  return false;
}

void HttpConnection::SendInternal(const base::Closure& callback,
                                  scoped_refptr<DrainableIOBuffer> buf) {
  while (buf->BytesRemaining() > 0) {
    int rv = socket_->Write(buf.get(), buf->BytesRemaining(),
                            base::Bind(&HttpConnection::OnSendInternalDone,
                                       base::Unretained(this), callback, buf));
    if (rv == ERR_IO_PENDING)
      return;

    if (rv < 0)
      break;
    buf->DidConsume(rv);
  }

  // The HttpConnection will be deleted by the callback since we only need to
  // serve a single request.
  callback.Run();
}

void HttpConnection::OnSendInternalDone(const base::Closure& callback,
                                        scoped_refptr<DrainableIOBuffer> buf,
                                        int rv) {
  if (rv < 0) {
    callback.Run();
    return;
  }
  buf->DidConsume(rv);
  SendInternal(callback, buf);
}

base::WeakPtr<HttpConnection> HttpConnection::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

}  // namespace test_server
}  // namespace net
