// Copyright (c) 2020 The Chromium Embedded Framework 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 "libcef/browser/media_router/media_router_manager.h"

#include "libcef/browser/browser_context.h"
#include "libcef/browser/thread_util.h"

#include "chrome/browser/media/router/media_router_factory.h"
#include "chrome/browser/media/router/media_routes_observer.h"
#include "chrome/browser/media/router/route_message_observer.h"
#include "chrome/browser/media/router/route_message_util.h"

namespace {

const int kTimeoutMs = 5 * 1000;
const char kDefaultPresentationUrl[] = "https://google.com";

}  // namespace

class CefMediaRoutesObserver : public media_router::MediaRoutesObserver {
 public:
  explicit CefMediaRoutesObserver(CefMediaRouterManager* manager)
      : media_router::MediaRoutesObserver(manager->GetMediaRouter()),
        manager_(manager) {}

  void OnRoutesUpdated(const std::vector<media_router::MediaRoute>& routes,
                       const std::vector<media_router::MediaRoute::Id>&
                           joinable_route_ids) override {
    manager_->routes_ = routes;
    manager_->NotifyCurrentRoutes();
  }

 private:
  CefMediaRouterManager* const manager_;

  DISALLOW_COPY_AND_ASSIGN(CefMediaRoutesObserver);
};

// Used to receive messages if PresentationConnection is not supported.
class CefRouteMessageObserver : public media_router::RouteMessageObserver {
 public:
  CefRouteMessageObserver(CefMediaRouterManager* manager,
                          const media_router::MediaRoute& route)
      : media_router::RouteMessageObserver(manager->GetMediaRouter(),
                                           route.media_route_id()),
        manager_(manager),
        route_(route) {}

  void OnMessagesReceived(
      CefMediaRouterManager::MediaMessageVector messages) override {
    manager_->OnMessagesReceived(route_, messages);
  }

 private:
  CefMediaRouterManager* const manager_;
  const media_router::MediaRoute route_;

  DISALLOW_COPY_AND_ASSIGN(CefRouteMessageObserver);
};

// Used for messaging and route status notifications with Cast.
class CefPresentationConnection : public blink::mojom::PresentationConnection {
 public:
  explicit CefPresentationConnection(
      CefMediaRouterManager* manager,
      const media_router::MediaRoute& route,
      media_router::mojom::RoutePresentationConnectionPtr connections)
      : manager_(manager),
        route_(route),
        connection_receiver_(this, std::move(connections->connection_receiver)),
        connection_remote_(std::move(connections->connection_remote)) {}

  void OnMessage(
      blink::mojom::PresentationConnectionMessagePtr message) override {
    CefMediaRouterManager::MediaMessageVector messages;
    if (message->is_message()) {
      messages.push_back(media_router::message_util::RouteMessageFromString(
          message->get_message()));
    } else if (message->is_data()) {
      messages.push_back(media_router::message_util::RouteMessageFromData(
          message->get_data()));
    }
    if (!messages.empty()) {
      manager_->OnMessagesReceived(route_, messages);
    }
  }

  void DidChangeState(
      blink::mojom::PresentationConnectionState state) override {
    // May result in |this| being deleted, so post async and allow the call
    // stack to unwind.
    CEF_POST_TASK(
        CEF_UIT,
        base::BindOnce(&CefMediaRouterManager::OnRouteStateChange,
                       manager_->weak_ptr_factory_.GetWeakPtr(), route_,
                       content::PresentationConnectionStateChangeInfo(state)));
  }

  void DidClose(
      blink::mojom::PresentationConnectionCloseReason reason) override {
    DidChangeState(blink::mojom::PresentationConnectionState::CLOSED);
  }

  void SendRouteMessage(const std::string& message) {
    connection_remote_->OnMessage(
        blink::mojom::PresentationConnectionMessage::NewMessage(message));
  }

 private:
  CefMediaRouterManager* const manager_;
  const media_router::MediaRoute route_;

  // Used to receive messages from the MRP.
  mojo::Receiver<blink::mojom::PresentationConnection> connection_receiver_;

  // Used to send messages to the MRP.
  mojo::Remote<blink::mojom::PresentationConnection> connection_remote_;

  DISALLOW_COPY_AND_ASSIGN(CefPresentationConnection);
};

CefMediaRouterManager::CefMediaRouterManager(CefBrowserContext* browser_context)
    : browser_context_(browser_context),
      query_result_manager_(GetMediaRouter()),
      weak_ptr_factory_(this) {
  // Perform initialization.
  GetMediaRouter()->OnUserGesture();

  query_result_manager_.AddObserver(this);

  // A non-empty presentation URL to required for discovery of Cast devices.
  query_result_manager_.SetSourcesForCastMode(
      media_router::MediaCastMode::PRESENTATION,
      {media_router::MediaSource::ForPresentationUrl(
          GURL(kDefaultPresentationUrl))},
      url::Origin());

  routes_observer_ = std::make_unique<CefMediaRoutesObserver>(this);
}

CefMediaRouterManager::~CefMediaRouterManager() {
  CEF_REQUIRE_UIT();
  for (auto& observer : observers_) {
    observers_.RemoveObserver(&observer);
    observer.OnMediaRouterDestroyed();
  }

  query_result_manager_.RemoveObserver(this);
}

void CefMediaRouterManager::AddObserver(Observer* observer) {
  CEF_REQUIRE_UIT();
  observers_.AddObserver(observer);
}

void CefMediaRouterManager::RemoveObserver(Observer* observer) {
  CEF_REQUIRE_UIT();
  observers_.RemoveObserver(observer);
}

void CefMediaRouterManager::NotifyCurrentSinks() {
  CEF_REQUIRE_UIT();
  for (auto& observer : observers_) {
    observer.OnMediaSinks(sinks_);
  }
}

void CefMediaRouterManager::NotifyCurrentRoutes() {
  CEF_REQUIRE_UIT();
  for (auto& observer : observers_) {
    observer.OnMediaRoutes(routes_);
  }
}

void CefMediaRouterManager::CreateRoute(
    const media_router::MediaSource::Id& source_id,
    const media_router::MediaSink::Id& sink_id,
    const url::Origin& origin,
    CreateRouteResultCallback callback) {
  GetMediaRouter()->CreateRoute(
      source_id, sink_id, origin, nullptr /* web_contents */,
      base::BindOnce(&CefMediaRouterManager::OnCreateRoute,
                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
      base::TimeDelta::FromMilliseconds(kTimeoutMs), false /* incognito */);
}

void CefMediaRouterManager::SendRouteMessage(
    const media_router::MediaRoute::Id& route_id,
    const std::string& message) {
  // Must use PresentationConnection to send messages if it exists.
  auto state = GetRouteState(route_id);
  if (state && state->presentation_connection_) {
    state->presentation_connection_->SendRouteMessage(message);
    return;
  }

  GetMediaRouter()->SendRouteMessage(route_id, message);
}

void CefMediaRouterManager::TerminateRoute(
    const media_router::MediaRoute::Id& route_id) {
  GetMediaRouter()->TerminateRoute(route_id);
}

void CefMediaRouterManager::OnResultsUpdated(const MediaSinkVector& sinks) {
  sinks_ = sinks;
  NotifyCurrentSinks();
}

media_router::MediaRouter* CefMediaRouterManager::GetMediaRouter() const {
  CEF_REQUIRE_UIT();
  return media_router::MediaRouterFactory::GetApiForBrowserContext(
      browser_context_);
}

void CefMediaRouterManager::OnCreateRoute(
    CreateRouteResultCallback callback,
    media_router::mojom::RoutePresentationConnectionPtr connection,
    const media_router::RouteRequestResult& result) {
  CEF_REQUIRE_UIT();
  if (result.route()) {
    CreateRouteState(*result.route(), std::move(connection));
  }

  std::move(callback).Run(result);
}

void CefMediaRouterManager::OnRouteStateChange(
    const media_router::MediaRoute& route,
    const content::PresentationConnectionStateChangeInfo& info) {
  CEF_REQUIRE_UIT();
  if (info.state == blink::mojom::PresentationConnectionState::CLOSED ||
      info.state == blink::mojom::PresentationConnectionState::TERMINATED) {
    RemoveRouteState(route.media_route_id());
  }

  for (auto& observer : observers_) {
    observer.OnMediaRouteStateChange(route, info);
  }
}

void CefMediaRouterManager::OnMessagesReceived(
    const media_router::MediaRoute& route,
    const MediaMessageVector& messages) {
  CEF_REQUIRE_UIT();
  for (auto& observer : observers_) {
    observer.OnMediaRouteMessages(route, messages);
  }
}

void CefMediaRouterManager::CreateRouteState(
    const media_router::MediaRoute& route,
    media_router::mojom::RoutePresentationConnectionPtr connection) {
  const auto route_id = route.media_route_id();
  auto state = std::make_unique<RouteState>();

  if (!connection.is_null()) {
    // PresentationConnection must be used for messaging and status
    // notifications if it exists.
    state->presentation_connection_ =
        std::make_unique<CefPresentationConnection>(this, route,
                                                    std::move(connection));
  } else {
    // Fallback if PresentationConnection is not supported.
    state->message_observer_ =
        std::make_unique<CefRouteMessageObserver>(this, route);
    state->state_subscription_ =
        GetMediaRouter()->AddPresentationConnectionStateChangedCallback(
            route_id,
            base::BindRepeating(&CefMediaRouterManager::OnRouteStateChange,
                                weak_ptr_factory_.GetWeakPtr(), route));
  }

  route_state_map_.insert(std::make_pair(route_id, std::move(state)));
}

CefMediaRouterManager::RouteState* CefMediaRouterManager::GetRouteState(
    const media_router::MediaRoute::Id& route_id) {
  const auto it = route_state_map_.find(route_id);
  if (it != route_state_map_.end())
    return it->second.get();
  return nullptr;
}

void CefMediaRouterManager::RemoveRouteState(
    const media_router::MediaRoute::Id& route_id) {
  auto it = route_state_map_.find(route_id);
  if (it != route_state_map_.end())
    route_state_map_.erase(it);
}
