// Copyright 2015 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 "buffet/http_transport_client.h"

#include <utility>

#include <base/bind.h>
#include <brillo/errors/error.h>
#include <brillo/http/http_utils.h>
#include <brillo/streams/memory_stream.h>
#include <weave/enum_to_string.h>

#include "buffet/weave_error_conversion.h"

namespace buffet {

namespace {

using weave::provider::HttpClient;

// The number of seconds each HTTP request will be allowed before timing out.
const int kRequestTimeoutSeconds = 30;

const char kErrorDomain[] = "buffet";

class ResponseImpl : public HttpClient::Response {
 public:
  ~ResponseImpl() override = default;
  explicit ResponseImpl(std::unique_ptr<brillo::http::Response> response)
      : response_{std::move(response)},
        data_{response_->ExtractDataAsString()} {}

  // HttpClient::Response implementation
  int GetStatusCode() const override { return response_->GetStatusCode(); }

  std::string GetContentType() const override {
    return response_->GetContentType();
  }

  std::string GetData() const override { return data_; }

 private:
  std::unique_ptr<brillo::http::Response> response_;
  std::string data_;
  DISALLOW_COPY_AND_ASSIGN(ResponseImpl);
};

}  // anonymous namespace

HttpTransportClient::HttpTransportClient()
    : transport_{brillo::http::Transport::CreateDefault()} {
  transport_->SetDefaultTimeout(
      base::TimeDelta::FromSeconds(kRequestTimeoutSeconds));
}

HttpTransportClient::~HttpTransportClient() {}

void HttpTransportClient::SendRequest(Method method,
                                      const std::string& url,
                                      const Headers& headers,
                                      const std::string& data,
                                      const SendRequestCallback& callback) {
  brillo::http::Request request(url, weave::EnumToString(method), transport_);
  request.AddHeaders(headers);
  if (!data.empty()) {
    auto stream = brillo::MemoryStream::OpenCopyOf(data, nullptr);
    CHECK(stream->GetRemainingSize());
    brillo::ErrorPtr cromeos_error;
    if (!request.AddRequestBody(std::move(stream), &cromeos_error)) {
      weave::ErrorPtr error;
      ConvertError(*cromeos_error, &error);
      transport_->RunCallbackAsync(
          FROM_HERE, base::Bind(callback, nullptr, base::Passed(&error)));
      return;
    }
  }

  callbacks_.emplace(
      request.GetResponse(base::Bind(&HttpTransportClient::OnSuccessCallback,
                                     weak_ptr_factory_.GetWeakPtr()),
                          base::Bind(&HttpTransportClient::OnErrorCallback,
                                     weak_ptr_factory_.GetWeakPtr())),
      callback);
}

void HttpTransportClient::OnSuccessCallback(
    int id,
    std::unique_ptr<brillo::http::Response> response) {
  auto it = callbacks_.find(id);
  if (it == callbacks_.end()) {
    LOG(INFO) << "Request has already been cancelled: " << id;
    return;
  }

  it->second.Run(std::unique_ptr<HttpClient::Response>{new ResponseImpl{
      std::move(response)}}, nullptr);
  callbacks_.erase(it);
}

void HttpTransportClient::OnErrorCallback(int id,
                                          const brillo::Error* brillo_error) {
  auto it = callbacks_.find(id);
  if (it == callbacks_.end()) {
    LOG(INFO) << "Request has already been cancelled: " << id;
    return;
  }

  weave::ErrorPtr error;
  ConvertError(*brillo_error, &error);
  it->second.Run(nullptr, std::move(error));
  callbacks_.erase(it);
}

void HttpTransportClient::SetOnline(bool online) {
  if (!online) {
    for (const auto &pair : callbacks_) {
      weave::ErrorPtr error;
      weave::Error::AddTo(&error, FROM_HERE, kErrorDomain, "offline",
                          "offline");
      transport_->RunCallbackAsync(
          FROM_HERE, base::Bind(pair.second, nullptr, base::Passed(&error)));
    }

    callbacks_.clear();
  }
}

}  // namespace buffet
