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

#include <istream>
#include <memory>
#include <ostream>
#include <string>
#include <vector>

#include "garnet/bin/http/http_adapters.h"
#include "garnet/bin/http/http_client.h"
#include "garnet/bin/http/http_errors.h"
#include "lib/fxl/logging.h"
#include "lib/url/gurl.h"

namespace http {

namespace oldhttp = ::fuchsia::net::oldhttp;

namespace {
const size_t kMaxRedirects = 20;
}  // namespace

URLLoaderImpl::URLLoaderImpl(Coordinator* coordinator)
    : coordinator_(coordinator) {}

URLLoaderImpl::~URLLoaderImpl() {}

void URLLoaderImpl::Start(oldhttp::URLRequest request, Callback callback) {
  callback_ = std::move(callback);
  coordinator_->RequestNetworkSlot(
      [this, request = std::move(request)](fit::closure on_inactive) mutable {
        StartInternal(std::move(request));
        on_inactive();
      });
}

void URLLoaderImpl::FollowRedirect(Callback callback) {
  FXL_NOTIMPLEMENTED();
  callback_ = std::move(callback);
  SendError(HTTP_ERR_NOT_IMPLEMENTED);
}

void URLLoaderImpl::QueryStatus(QueryStatusCallback callback) {
  oldhttp::URLLoaderStatus status;
  FXL_NOTIMPLEMENTED();
  status.error = MakeHttpError(HTTP_ERR_NOT_IMPLEMENTED);
  callback(std::move(status));
}

void URLLoaderImpl::SendError(int error_code) {
  oldhttp::URLResponse response;
  response.error = MakeHttpError(error_code);
  if (current_url_.is_valid()) {
    response.url = current_url_.spec();
  }
  SendResponse(std::move(response));
}

void URLLoaderImpl::FollowRedirectInternal() { /* TODO(toshik) */
}

void URLLoaderImpl::SendResponse(oldhttp::URLResponse response) {
  Callback callback;
  std::swap(callback_, callback);
  callback(std::move(response));
}

void URLLoaderImpl::StartInternal(oldhttp::URLRequest request) {
  std::string url_str = request.url;
  std::string method = request.method;
  std::map<std::string, std::string> extra_headers;
  std::unique_ptr<http::UploadElementReader> request_body_reader;

  if (request.headers) {
    for (size_t i = 0; i < request.headers->size(); ++i)
      extra_headers[request.headers->at(i).name] = request.headers->at(i).value;
  }

  if (request.body) {
    // TODO(kulakowski) Implement responses into a shared_buffer
    if (request.body->is_stream()) {
      request_body_reader = std::make_unique<http::SocketUploadElementReader>(
          std::move(request.body->stream()));
    } else {
      FXL_DCHECK(request.body->is_buffer());
      request_body_reader = std::make_unique<http::VmoUploadElementReader>(
          std::move(request.body->buffer().vmo), request.body->buffer().size);
    }
  }

  response_body_mode_ = request.response_body_mode;

  asio::io_service io_service;
  size_t redirectsLeft = kMaxRedirects;

  current_url_ = url::GURL(url_str);
  if (!current_url_.is_valid()) {
    SendError(HTTP_ERR_INVALID_ARGUMENT);
    return;
  }

  do {
    if (current_url_.SchemeIs("https")) {
#ifdef NETWORK_SERVICE_USE_HTTPS
      asio::ssl::context ctx(asio::ssl::context::sslv23);
#ifndef NETWORK_SERVICE_DISABLE_CERT_VERIFY
      ctx.set_default_verify_paths();
#endif
      HTTPClient<asio::ssl::stream<tcp::socket>> c(this, io_service, ctx);
      zx_status_t result = c.CreateRequest(
          current_url_.host(),
          current_url_.path() +
              (current_url_.has_query() ? "?" + current_url_.query() : ""),
          method, extra_headers, std::move(request_body_reader));
      if (result != ZX_OK) {
        SendError(HTTP_ERR_INVALID_ARGUMENT);
        return;
      }
      c.Start(current_url_.host(),
              current_url_.has_port() ? current_url_.port() : "https");
      io_service.run();

      if (c.status_code_ == 301 || c.status_code_ == 302) {
        current_url_ = url::GURL(c.redirect_location_);
        if (!current_url_.is_valid()) {
          SendError(HTTP_ERR_INVALID_RESPONSE);
          return;
        }
        // Follow redirect
        io_service.reset();
        continue;
      }
#else
      FXL_LOG(WARNING) << "https is not built-in. "
                          "please build with NETWORK_SERVICE_USE_HTTPS";
      SendError(HTTP_ERR_INVALID_ARGUMENT);
      return;
#endif
    } else if (current_url_.SchemeIs("http")) {
      HTTPClient<tcp::socket> c(this, io_service);
      zx_status_t result = c.CreateRequest(
          current_url_.host(),
          current_url_.path() +
              (current_url_.has_query() ? "?" + current_url_.query() : ""),
          method, extra_headers, std::move(request_body_reader));
      if (result != ZX_OK) {
        SendError(HTTP_ERR_INVALID_ARGUMENT);
        return;
      }
      c.Start(current_url_.host(),
              current_url_.has_port() ? current_url_.port() : "http");
      io_service.run();

      if (c.status_code_ == 301 || c.status_code_ == 302) {
        current_url_ = url::GURL(c.redirect_location_);
        if (!current_url_.is_valid()) {
          SendError(HTTP_ERR_INVALID_RESPONSE);
          return;
        }
        // Follow redirect
        io_service.reset();
        continue;
      }
    } else {
      // unknown protocol
      SendError(HTTP_ERR_INVALID_ARGUMENT);
      return;
    }
    // Success without redirect
    return;
  } while (--redirectsLeft);
  SendError(HTTP_ERR_TOO_MANY_REDIRECTS);
}

}  // namespace http
