// Copyright 2014 The Chromium OS 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 <brillo/http/http_connection_fake.h>

#include <base/logging.h>
#include <brillo/bind_lambda.h>
#include <brillo/http/http_request.h>
#include <brillo/mime_utils.h>
#include <brillo/streams/memory_stream.h>
#include <brillo/strings/string_utils.h>

namespace brillo {
namespace http {
namespace fake {

Connection::Connection(const std::string& url,
                       const std::string& method,
                       const std::shared_ptr<http::Transport>& transport)
    : http::Connection(transport), request_(url, method) {
  VLOG(1) << "fake::Connection created: " << method;
}

Connection::~Connection() {
  VLOG(1) << "fake::Connection destroyed";
}

bool Connection::SendHeaders(const HeaderList& headers,
                             brillo::ErrorPtr* /* error */) {
  request_.AddHeaders(headers);
  return true;
}

bool Connection::SetRequestData(StreamPtr stream,
                                brillo::ErrorPtr* /* error */) {
  request_.SetData(std::move(stream));
  return true;
}

bool Connection::FinishRequest(brillo::ErrorPtr*  /* error */) {
  using brillo::string_utils::ToString;
  request_.AddHeaders(
      {{request_header::kContentLength, ToString(request_.GetData().size())}});
  fake::Transport* transport = static_cast<fake::Transport*>(transport_.get());
  CHECK(transport) << "Expecting a fake transport";
  auto handler = transport->GetHandler(request_.GetURL(), request_.GetMethod());
  if (handler.is_null()) {
    LOG(ERROR) << "Received unexpected " << request_.GetMethod()
               << " request at " << request_.GetURL();
    response_.ReplyText(status_code::NotFound,
                        "<html><body>Not found</body></html>",
                        brillo::mime::text::kHtml);
  } else {
    handler.Run(request_, &response_);
  }
  return true;
}

RequestID Connection::FinishRequestAsync(
    const SuccessCallback& success_callback,
    const ErrorCallback& error_callback) {
  // Make sure the produced Closure holds a reference to the instance of this
  // connection.
  auto connection = std::static_pointer_cast<Connection>(shared_from_this());
  auto callback = [](std::shared_ptr<Connection> connection,
                     const SuccessCallback& success_callback,
                     const ErrorCallback& error_callback) {
    connection->FinishRequestAsyncHelper(success_callback, error_callback);
  };
  transport_->RunCallbackAsync(FROM_HERE,
                               base::Bind(callback,
                                          base::Passed(&connection),
                                          success_callback,
                                          error_callback));
  return 1;
}

void Connection::FinishRequestAsyncHelper(
    const SuccessCallback& success_callback,
    const ErrorCallback& error_callback) {
  brillo::ErrorPtr error;
  if (!FinishRequest(&error)) {
    error_callback.Run(1, error.get());
  } else {
    std::unique_ptr<Response> response{new Response{shared_from_this()}};
    success_callback.Run(1, std::move(response));
  }
}

int Connection::GetResponseStatusCode() const {
  return response_.GetStatusCode();
}

std::string Connection::GetResponseStatusText() const {
  return response_.GetStatusText();
}

std::string Connection::GetProtocolVersion() const {
  return response_.GetProtocolVersion();
}

std::string Connection::GetResponseHeader(
    const std::string& header_name) const {
  return response_.GetHeader(header_name);
}

StreamPtr Connection::ExtractDataStream(brillo::ErrorPtr* error) {
  // HEAD requests must not return body.
  if (request_.GetMethod() != request_type::kHead) {
    return MemoryStream::OpenRef(response_.GetData(), error);
  } else {
    // Return empty data stream for HEAD requests.
    return MemoryStream::OpenCopyOf(nullptr, 0, error);
  }
}

}  // namespace fake
}  // namespace http
}  // namespace brillo
