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

#include "components/cast_receiver/browser/streaming_runtime_application.h"

#include "base/strings/stringprintf.h"
#include "components/cast/message_port/platform_message_port.h"
#include "components/cast_receiver/browser/application_client.h"
#include "components/cast_receiver/browser/public/embedder_application.h"
#include "components/cast_receiver/browser/public/message_port_service.h"
#include "components/cast_streaming/common/public/app_ids.h"
#include "components/cast_streaming/common/public/cast_streaming_url.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"

namespace cast_receiver {
namespace {

constexpr char kCastTransportBindingName[] = "cast.__platform__.cast_transport";

constexpr char kStreamingPageUrlTemplate[] =
    "data:text/html;charset=UTF-8, <video style='position:absolute; "
    "top:50%%; left:50%%; transform:translate(-50%%,-50%%); "
    "max-width:100%%; max-height:100%%; min-width: 100%%; min-height: 100%%' "
    "src='%s'></video>";

}  // namespace

StreamingRuntimeApplication::StreamingRuntimeApplication(
    std::string cast_session_id,
    ApplicationConfig app_config,
    ApplicationClient& application_client)
    : RuntimeApplicationBase(std::move(cast_session_id),
                             std::move(app_config),
                             application_client) {}

StreamingRuntimeApplication::~StreamingRuntimeApplication() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  StopApplication(EmbedderApplication::ApplicationStopReason::kUserRequest,
                  net::OK);
}

void StreamingRuntimeApplication::OnStreamingSessionStarted() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  OnPageNavigationComplete();
}

void StreamingRuntimeApplication::OnError() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  LOG(WARNING) << "Streaming session for " << *this << " has hit an error!";
  StopApplication(EmbedderApplication::ApplicationStopReason::kRuntimeError,
                  net::ERR_FAILED);
}

void StreamingRuntimeApplication::Launch(StatusCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  DCHECK(embedder_application().GetWebContents());
  SetContentPermissions(*embedder_application().GetWebContents());

  // Bind Cast Transport.
  auto* message_port_service = embedder_application().GetMessagePortService();
  DCHECK(message_port_service);
  std::unique_ptr<cast_api_bindings::MessagePort> server_port;
  std::unique_ptr<cast_api_bindings::MessagePort> client_port;
  cast_api_bindings::CreatePlatformMessagePortPair(&client_port, &server_port);
  message_port_service->ConnectToPortAsync(kCastTransportBindingName,
                                           std::move(client_port));

  // Initialize the streaming receiver.
  receiver_session_client_ = std::make_unique<StreamingReceiverSessionClient>(
      task_runner(), application_client().network_context_getter(),
      std::move(server_port), embedder_application().GetWebContents(), this,
      embedder_application().GetStreamingConfigManager(),
      /* supports_audio= */ GetAppId() !=
          cast_streaming::GetIosAppStreamingAudioVideoAppId(),
      /* supports_video= */ true);
  receiver_session_client_->LaunchStreamingReceiverAsync();

  // Application is initialized now - we can load the URL.
  NavigateToPage(GURL(base::StringPrintf(
      kStreamingPageUrlTemplate,
      cast_streaming::GetCastStreamingMediaSourceUrl().spec().c_str())));

  // Signal that application is launching.
  std::move(callback).Run(OkStatus());
}

void StreamingRuntimeApplication::StopApplication(
    EmbedderApplication::ApplicationStopReason stop_reason,
    net::Error net_error_code) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!receiver_session_client_) {
    DLOG(WARNING) << "Streaming session never started prior to " << *this
                  << " stop.";
  }

  receiver_session_client_.reset();
  RuntimeApplicationBase::StopApplication(stop_reason, net_error_code);
}

bool StreamingRuntimeApplication::IsStreamingApplication() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return true;
}

}  // namespace cast_receiver
