// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/base/protobuf_http_stream_request.h"

#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/notimplemented.h"
#include "base/time/time.h"
#include "remoting/base/http_status.h"
#include "remoting/base/protobuf_http_client.h"
#include "remoting/base/protobuf_http_request_config.h"
#include "remoting/base/protobuf_http_stream_parser.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "third_party/protobuf/src/google/protobuf/message_lite.h"

namespace remoting {

// static
constexpr base::TimeDelta
    ProtobufHttpStreamRequest::kStreamReadyTimeoutDuration;

ProtobufHttpStreamRequest::ProtobufHttpStreamRequest(
    std::unique_ptr<ProtobufHttpRequestConfig> request_config)
    : ProtobufHttpRequestBase(std::move(request_config)) {
  // It's unclear what should be done if a server responds SERVICE_UNAVAILABLE
  // after the stream is open, since the stream might be stateful so we can't
  // reopen the stream opaquely. We don't bother to implement retries for
  // stream requests since they are only used by FTL, which already has its own
  // retry logic.
  DCHECK(!config().retry_policy) << "Stream requests don't support retries.";
}

ProtobufHttpStreamRequest::~ProtobufHttpStreamRequest() = default;

void ProtobufHttpStreamRequest::SetStreamReadyCallback(
    base::OnceClosure callback) {
  stream_ready_callback_ = std::move(callback);
}

void ProtobufHttpStreamRequest::SetStreamClosedCallback(
    StreamClosedCallback callback) {
  stream_closed_callback_ = std::move(callback);
}

void ProtobufHttpStreamRequest::OnMessage(const std::string& message) {
  std::unique_ptr<google::protobuf::MessageLite> protobuf_message(
      default_message_->New());
  if (protobuf_message->ParseFromString(message)) {
    message_callback_.Run(std::move(protobuf_message));
  } else {
    LOG(ERROR) << "Failed to parse a stream message.";
  }
}

void ProtobufHttpStreamRequest::OnStreamClosed(const HttpStatus& status) {
  DCHECK(stream_closed_callback_);
  DCHECK(invalidator_);

  // Move |invalidator_| out of |this| as the callback can potentially delete
  // |this|.
  auto invalidator = std::move(invalidator_);
  std::move(stream_closed_callback_).Run(status);
  std::move(invalidator).Run();
}

void ProtobufHttpStreamRequest::OnAuthFailed(const HttpStatus& status) {
  // Can't call OnStreamClosed here since it invokes the |invalidator_|.
  std::move(stream_closed_callback_).Run(status);
}

void ProtobufHttpStreamRequest::StartRequestInternal(
    network::mojom::URLLoaderFactory* loader_factory) {
  DCHECK(default_message_);
  DCHECK(stream_ready_callback_);
  DCHECK(stream_closed_callback_);
  DCHECK(message_callback_);

  stream_ready_timeout_timer_.Start(
      FROM_HERE, kStreamReadyTimeoutDuration, this,
      &ProtobufHttpStreamRequest::OnStreamReadyTimeout);

  // Safe to use unretained, as callbacks won't be called after |stream_parser_|
  // is deleted.
  stream_parser_ = std::make_unique<ProtobufHttpStreamParser>(
      base::BindRepeating(&ProtobufHttpStreamRequest::OnMessage,
                          base::Unretained(this)),
      base::BindRepeating(&ProtobufHttpStreamRequest::OnStreamClosed,
                          base::Unretained(this)));
  url_loader_->DownloadAsStream(loader_factory, this);
}

base::TimeDelta ProtobufHttpStreamRequest::GetRequestTimeoutDuration() const {
  return base::TimeDelta();
}

void ProtobufHttpStreamRequest::OnDataReceived(std::string_view string_view,
                                               base::OnceClosure resume) {
  if (stream_ready_timeout_timer_.IsRunning()) {
    stream_ready_timeout_timer_.Stop();
  }

  if (stream_ready_callback_) {
    std::move(stream_ready_callback_).Run();
  }

  DCHECK(stream_parser_);
  stream_parser_->Append(string_view);
  std::move(resume).Run();
}

void ProtobufHttpStreamRequest::OnComplete(bool success) {
  // |success| can be true even if the server returns 4xx or 5xx error.
  OnStreamClosed(GetUrlLoaderStatus());
}

void ProtobufHttpStreamRequest::OnRetry(base::OnceClosure start_retry) {
  NOTIMPLEMENTED();
}

void ProtobufHttpStreamRequest::OnStreamReadyTimeout() {
  OnStreamClosed(HttpStatus(HttpStatus::Code::DEADLINE_EXCEEDED,
                            "Stream connection failed: timeout"));
}

}  // namespace remoting
