#include "region.h"

#include <curl/curl.h>
#include <iostream>
#include <sstream>
#include <string>

// For some reason, the libjsoncpp package installs to /usr/include/jsoncpp/json
// instead of /usr{,/local}/include/json
#include <jsoncpp/json/json.h>

#include "errors.h"

namespace speedtest {
namespace {

bool AddUrl(const Json::Value &url_json, std::vector<http::Url> *urls) {
  if (!url_json.isString()) {
    return false;
  }
  http::Url url = http::Url(url_json.asString());
  if (!url.ok()) {
    return false;
  }
  urls->push_back(url);
  return true;
}

}  // namesapce

std::string DescribeRegion(const Region &region) {
  if (region.id.empty() && region.name.empty()) {
    return region.urls.front().url();
  }
  if (region.id.empty()) {
    return region.name;
  }
  if (region.name.empty()) {
    return region.id;
  }
  std::stringstream ss;
  ss << region.name << " (" << region.id << ")";
  return ss.str();
}

RegionResult LoadRegions(RegionOptions options) {
  RegionResult result;
  result.start_time = SystemTimeMicros();
  if (!options.request_factory) {
    result.status = Status(StatusCode::INVALID_ARGUMENT,
                           "request factory not set");
    result.end_time = SystemTimeMicros();
    return result;
  }

  if (!options.global) {
    if (options.verbose) {
      std::cout << "Explicit server list:\n";
      for (const auto &url : options.regional_urls) {
        std::cout << "  " << url.url() << "\n";
      }
    }
    for (const http::Url &url : options.regional_urls) {
      Region region;
      region.urls.emplace_back(url.url());
      result.regions.emplace_back(region);
    }
    result.status = Status::OK;
    result.end_time = SystemTimeMicros();
    return result;
  }

  http::Url config_url(options.global_url);
  config_url.set_path("/fiber/config");
  if (options.verbose) {
    std::cout << "Loading regions from " << config_url.url() << "\n";
  }
  http::Request::Ptr request = options.request_factory(config_url);
  request->set_url(config_url);
  request->set_timeout_millis(500);
  std::string json;
  CURLcode code = request->Get([&](void *data, size_t size){
    json.assign(static_cast<const char *>(data), size);
  });
  if (code != CURLE_OK) {
    result.status = Status(StatusCode::INTERNAL, http::ErrorString(code));
  } else {
    result.status = ParseRegions(json, &result.regions);
  }
  result.end_time = SystemTimeMicros();
  return result;
}

Status ParseRegions(const std::string &json, std::vector<Region> *regions) {
  if (!regions) {
    return Status(StatusCode::FAILED_PRECONDITION, "Regions is null");
  }

  Json::Reader reader;
  Json::Value root;
  if (!reader.parse(json, root, false)) {
    return Status(StatusCode::INVALID_ARGUMENT, "Failed to parse regions JSON");
  }

  if (!root.isMember("regions") || !root["regions"].isArray()) {
    return Status(StatusCode::INVALID_ARGUMENT, "no regions element found");
  }
  for (const auto &it : root["regions"]) {
    Region region;

    if (!it.isMember("id")) {
      return Status(StatusCode::INVALID_ARGUMENT, "Region missing id");
    }
    if (!it["id"].isString()) {
      return Status(StatusCode::INVALID_ARGUMENT, "Region id not a string");
    }
    region.id = it["id"].asString();

    if (it.isMember("name")) {
      if (!it["name"].isString()) {
        return Status(StatusCode::INVALID_ARGUMENT, "Region name not a string");
      }
      region.name = it["name"].asString();
    }

    if (!it.isMember("url")) {
      return Status(StatusCode::INVALID_ARGUMENT, "Region URL missing");
    }
    if (it["url"].isString()) {
      if (!AddUrl(it["url"], &region.urls)) {
        return Status(StatusCode::INVALID_ARGUMENT,
                      "Failed to parse region URL");
      }
    } else if (it["url"].isArray()) {
      for (const auto &url_it : it["url"]) {
        if (!AddUrl(url_it, &region.urls)) {
          return Status(StatusCode::INVALID_ARGUMENT,
                        "Failed to parse region URL");
        }
      }
      if (region.urls.empty()) {
        return Status(StatusCode::INVALID_ARGUMENT, "Region missing URLs");
      }
    } else {
      return Status(StatusCode::INVALID_ARGUMENT,
                    "Region URL not string or array");
    }

    regions->emplace_back(region);
  }
  return Status::OK;
}

}  // namespace
