// Copyright (c) 2018 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 "chrome/chrome_cleaner/http/mock_http_agent_factory.h"

#include <stdint.h>

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "base/logging.h"
#include "chrome/chrome_cleaner/http/http_agent.h"
#include "chrome/chrome_cleaner/http/http_agent_factory.h"
#include "chrome/chrome_cleaner/http/http_response.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chrome_cleaner {

namespace {

// Class that provides a response based on how the MockHttpAgentConfig is
// configured.
class MockHttpResponse : public chrome_cleaner::HttpResponse {
 public:
  explicit MockHttpResponse(MockHttpAgentConfig* config) : config_(config) {
    DCHECK(config);
  }

  ~MockHttpResponse() override = default;

  // chrome_cleaner::HttpResponse:
  bool GetStatusCode(uint16_t* status_code) override {
    if (config_->GetCurrentCalls().get_status_code_succeeds) {
      *status_code = static_cast<uint16_t>(
          config_->GetCurrentCalls().get_status_code_result);
    }
    return config_->GetCurrentCalls().get_status_code_succeeds;
  }

  bool GetContentLength(bool* has_content_length,
                        size_t* content_length) override {
    ADD_FAILURE() << "This method should not be called.";
    return false;
  }

  bool GetContentType(bool* has_content_type,
                      base::string16* content_type) override {
    ADD_FAILURE() << "This method should not be called.";
    return false;
  }

  bool HasData(bool* has_data) override {
    if (config_->GetCurrentCalls().has_data_succeeds)
      *has_data = !config_->GetCurrentCalls().read_data_result.empty();
    return config_->GetCurrentCalls().has_data_succeeds;
  }

  bool ReadData(char* buffer, size_t* count) override {
    MockHttpAgentConfig::Calls& calls = config_->GetCurrentCalls();

    bool succeeds = calls.read_data_succeeds_by_default;
    if (!calls.read_data_success_sequence.empty()) {
      succeeds = calls.read_data_success_sequence[0];
      calls.read_data_success_sequence.erase(
          calls.read_data_success_sequence.begin());
    }

    if (succeeds)
      config_->ReadData(buffer, count);
    return succeeds;
  }

 private:
  MockHttpAgentConfig* config_{nullptr};

  DISALLOW_COPY_AND_ASSIGN(MockHttpResponse);
};

// Class that acts as an HttpAgent based on how the MockHttpAgentConfig is
// configured.
class MockHttpAgent : public chrome_cleaner::HttpAgent {
 public:
  explicit MockHttpAgent(MockHttpAgentConfig* config) : config_(config) {
    DCHECK(config);
  }

  ~MockHttpAgent() override = default;

  // chrome_cleaner::HttpAgent:
  std::unique_ptr<chrome_cleaner::HttpResponse> Post(
      const base::string16& host,
      uint16_t port,
      const base::string16& path,
      bool secure,
      const base::string16& extra_headers,
      const std::string& body,
      const net::NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
    const bool post_succeeds = config_->GetCurrentCalls().request_succeeds;
    MockHttpAgentConfig::RequestData post_data;
    post_data.host = host;
    post_data.port = port;
    post_data.path = path;
    post_data.secure = secure;
    post_data.extra_headers = extra_headers;
    post_data.body = body;
    config_->AddRequestData(post_data);

    if (post_succeeds)
      return std::make_unique<MockHttpResponse>(config_);
    return std::unique_ptr<MockHttpResponse>();
  }

  // chrome_cleaner::HttpAgent:
  std::unique_ptr<chrome_cleaner::HttpResponse> Get(
      const base::string16& host,
      uint16_t port,
      const base::string16& path,
      bool secure,
      const base::string16& extra_headers,
      const net::NetworkTrafficAnnotationTag& /*traffic_annotation*/) override {
    const bool get_succeeds = config_->GetCurrentCalls().request_succeeds;
    MockHttpAgentConfig::RequestData get_data;
    get_data.host = host;
    get_data.port = port;
    get_data.path = path;
    get_data.secure = secure;
    get_data.extra_headers = extra_headers;
    config_->AddRequestData(get_data);

    if (get_succeeds)
      return std::make_unique<MockHttpResponse>(config_);
    return std::unique_ptr<MockHttpResponse>();
  }

 private:
  MockHttpAgentConfig* config_{nullptr};

  DISALLOW_COPY_AND_ASSIGN(MockHttpAgent);
};

}  // namespace

MockHttpAgentConfig::Calls::Calls(HttpStatus status)
    : get_status_code_result(status) {}

MockHttpAgentConfig::Calls::Calls(const Calls& other) = default;

MockHttpAgentConfig::Calls::~Calls() = default;

MockHttpAgentConfig::Calls& MockHttpAgentConfig::Calls::operator=(
    const MockHttpAgentConfig::Calls& other) = default;

MockHttpAgentConfig::RequestData::RequestData() = default;

MockHttpAgentConfig::RequestData::RequestData(const RequestData& other) =
    default;

MockHttpAgentConfig::RequestData::~RequestData() = default;

MockHttpAgentConfig::RequestData& MockHttpAgentConfig::RequestData::operator=(
    const MockHttpAgentConfig::RequestData& other) = default;

MockHttpAgentConfig::MockHttpAgentConfig() = default;

MockHttpAgentConfig::~MockHttpAgentConfig() = default;

size_t MockHttpAgentConfig::AddCalls(const Calls& calls) {
  calls_.push_back(calls);
  return calls_.size() - 1;
}

MockHttpAgentConfig::Calls& MockHttpAgentConfig::GetCurrentCalls() {
  if (current_index_ >= calls_.size()) {
    static Calls default_calls(HttpStatus::kOk);
    ADD_FAILURE() << "Did not expect more than " << calls_.size() << " tries";
    return default_calls;
  }
  return calls_[current_index_];
}

void MockHttpAgentConfig::ReadData(char* buffer, size_t* count) {
  if (current_index_ >= calls_.size()) {
    ADD_FAILURE() << "Reading data for an unexpected call";
    *count = 0;
    return;
  }
  Calls& calls = calls_[current_index_];
  *count = std::min(*count, calls.read_data_result.size());
  memcpy(buffer, calls.read_data_result.c_str(), *count);
  calls.read_data_result = calls.read_data_result.substr(*count);
}

void MockHttpAgentConfig::AddRequestData(const RequestData& request_data) {
  ASSERT_EQ(request_data_.size(), current_index_)
      << "MockHttpAgentConfig does not support creating multiple agents "
      << "without calling Post or Get on each before creating the next one. "
      << "Suggest adding support to MockHttpAgentConfig for that if necessary, "
      << "or updating your code to avoid this.";
  request_data_.push_back(request_data);
}

MockHttpAgentFactory::MockHttpAgentFactory(MockHttpAgentConfig* config)
    : config_(config) {
  DCHECK(config);
}

std::unique_ptr<chrome_cleaner::HttpAgent>
MockHttpAgentFactory::CreateHttpAgent() {
  // Set the configuration index to the next one (one per HttpAgent).
  if (config_->current_index_ == MockHttpAgentConfig::kInvalidIndex)
    config_->current_index_ = 0;
  else
    ++config_->current_index_;

  return std::make_unique<MockHttpAgent>(config_);
}

}  // namespace chrome_cleaner
