// Copyright 2018 The Fuchsia 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 "src/media/playback/mediaplayer/demux/http_reader.h"

#include <fuchsia/net/oldhttp/cpp/fidl.h>
#include <lib/async/default.h>

#include "garnet/bin/http/http_errors.h"
#include "lib/fidl/cpp/clone.h"
#include "src/lib/fxl/logging.h"

namespace media_player {

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

namespace {

const char* kContentLengthHeaderName = "Content-Length";
const char* kAcceptRangesHeaderName = "Accept-Ranges";
const char* kAcceptRangesHeaderBytesValue = "bytes";
const char* kRangeHeaderName = "Range";

constexpr uint32_t kStatusOk = 200u;
constexpr uint32_t kStatusPartialContent = 206u;
constexpr uint32_t kStatusNotFound = 404u;

}  // namespace

// static
std::shared_ptr<HttpReader> HttpReader::Create(
    component::StartupContext* startup_context, const std::string& url,
    fidl::VectorPtr<fuchsia::net::oldhttp::HttpHeader> headers) {
  return std::make_shared<HttpReader>(startup_context, url, std::move(headers));
}

HttpReader::HttpReader(
    component::StartupContext* startup_context, const std::string& url,
    fidl::VectorPtr<fuchsia::net::oldhttp::HttpHeader> headers)
    : url_(url),
      headers_(std::move(headers)),
      ready_(async_get_default_dispatcher()) {
  http::HttpServicePtr network_service =
      startup_context->ConnectToEnvironmentService<http::HttpService>();

  network_service->CreateURLLoader(url_loader_.NewRequest());

  http::URLRequest url_request;
  url_request.url = url_;
  url_request.method = "HEAD";
  url_request.auto_follow_redirects = true;
  if (headers_) {
    url_request.headers = fidl::Clone(headers_);
  }

  url_loader_->Start(std::move(url_request), [this](
                                                 http::URLResponse response) {
    if (response.error) {
      FXL_LOG(ERROR) << "HEAD response error " << response.error->code << " "
                     << (response.error->description
                             ? response.error->description
                             : "<no description>");
      status_ = response.error->code == ::http::HTTP_ERR_NAME_NOT_RESOLVED
                    ? ZX_ERR_NOT_FOUND
                    : ZX_ERR_INTERNAL;
      ready_.Occur();
      return;
    }

    if (response.status_code != kStatusOk) {
      FXL_LOG(ERROR) << "HEAD response status code " << response.status_code;
      status_ = response.status_code == kStatusNotFound ? ZX_ERR_NOT_FOUND
                                                        : ZX_ERR_INTERNAL;
      ready_.Occur();
      return;
    }

    for (const http::HttpHeader& header : *response.headers) {
      if (header.name == kContentLengthHeaderName) {
        size_ = std::stoull(header.value);
      } else if (header.name == kAcceptRangesHeaderName &&
                 header.value == kAcceptRangesHeaderBytesValue) {
        can_seek_ = true;
      }
    }

    ready_.Occur();
  });
}

HttpReader::~HttpReader() {}

void HttpReader::Describe(DescribeCallback callback) {
  ready_.When([this, callback = std::move(callback)]() {
    callback(status_, size_, can_seek_);
  });
}

void HttpReader::ReadAt(size_t position, uint8_t* buffer, size_t bytes_to_read,
                        ReadAtCallback callback) {
  ready_.When([this, position, buffer, bytes_to_read,
               callback = std::move(callback)]() mutable {
    if (status_ != ZX_OK) {
      callback(status_, 0);
      return;
    }

    if (!can_seek_ && position != 0) {
      callback(ZX_ERR_INVALID_ARGS, 0);
      return;
    }

    read_at_position_ = position;
    read_at_buffer_ = buffer;

    if (read_at_position_ + bytes_to_read > size_) {
      read_at_bytes_to_read_ = size_ - read_at_position_;
    } else {
      read_at_bytes_to_read_ = bytes_to_read;
    }

    read_at_bytes_remaining_ = read_at_bytes_to_read_;
    read_at_callback_ = std::move(callback);

    if (!socket_ || socket_position_ != read_at_position_) {
      socket_.reset();
      socket_position_ = kUnknownSize;
      LoadAndReadFromSocket();
      return;
    }

    ReadFromSocket();
  });
}

void HttpReader::ReadFromSocket() {
  while (true) {
    size_t byte_count = 0;
    zx_status_t status = socket_.read(0u, read_at_buffer_,
                                      read_at_bytes_remaining_, &byte_count);

    if (status == ZX_ERR_SHOULD_WAIT) {
      waiter_ = std::make_unique<async::Wait>(
          socket_.get(), ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED);

      waiter_->set_handler([this](async_dispatcher_t* dispatcher,
                                  async::Wait* wait, zx_status_t status,
                                  const zx_packet_signal_t* signal) {
        if (status != ZX_OK) {
          if (status != ZX_ERR_CANCELED) {
            FXL_LOG(ERROR) << "AsyncWait failed, status " << status;
          }

          FailReadAt(status);
          return;
        }

        ReadFromSocket();
      });

      waiter_->Begin(async_get_default_dispatcher());

      break;
    }

    waiter_.reset();

    if (status != ZX_OK) {
      FXL_LOG(ERROR) << "zx::socket::read failed, status " << status;
      FailReadAt(status);
      break;
    }

    read_at_buffer_ += byte_count;
    read_at_bytes_remaining_ -= byte_count;
    socket_position_ += byte_count;

    if (read_at_bytes_remaining_ == 0) {
      CompleteReadAt(ZX_OK, read_at_bytes_to_read_);
      break;
    }
  }
}

void HttpReader::CompleteReadAt(zx_status_t status, size_t bytes_read) {
  ReadAtCallback read_at_callback;
  read_at_callback_.swap(read_at_callback);
  read_at_callback(status, bytes_read);
}

void HttpReader::FailReadAt(zx_status_t status) {
  status_ = status;
  socket_.reset();
  socket_position_ = kUnknownSize;
  CompleteReadAt(status_, 0);
}

void HttpReader::LoadAndReadFromSocket() {
  FXL_DCHECK(!socket_);

  if (!can_seek_ && read_at_position_ != 0) {
    FailReadAt(ZX_ERR_INVALID_ARGS);
    return;
  }

  http::URLRequest request;
  request.url = url_;
  request.method = "GET";
  request.auto_follow_redirects = true;
  if (headers_) {
    request.headers = fidl::Clone(headers_);
  }

  if (read_at_position_ != 0) {
    std::ostringstream value;
    value << kAcceptRangesHeaderBytesValue << "=" << read_at_position_ << "-";

    http::HttpHeader header;
    header.name = kRangeHeaderName;
    header.value = value.str();
    request.headers.push_back(std::move(header));
  }

  url_loader_->Start(std::move(request), [this](http::URLResponse response) {
    if (response.status_code != kStatusOk &&
        response.status_code != kStatusPartialContent) {
      FXL_LOG(WARNING) << "GET response status code " << response.status_code;
      FailReadAt(ZX_ERR_INTERNAL);
      return;
    }

    socket_ = std::move(response.body->stream());
    socket_position_ = read_at_position_;

    ReadFromSocket();
  });
}

}  // namespace media_player
