// 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_impl.h"

#include "libcef/browser/media_router/media_route_impl.h"
#include "libcef/browser/media_router/media_router_manager.h"
#include "libcef/browser/media_router/media_sink_impl.h"
#include "libcef/browser/media_router/media_source_impl.h"
#include "libcef/browser/thread_util.h"

namespace {

// Do not keep a reference to the object returned by this method.
CefBrowserContext* GetBrowserContext(const CefBrowserContext::Getter& getter) {
  CEF_REQUIRE_UIT();
  DCHECK(!getter.is_null());

  // Will return nullptr if the BrowserContext has been destroyed.
  return getter.Run();
}

}  // namespace

class CefRegistrationImpl : public CefRegistration,
                            public CefMediaRouterManager::Observer {
 public:
  explicit CefRegistrationImpl(CefRefPtr<CefMediaObserver> observer)
      : observer_(observer) {
    DCHECK(observer_);
  }

  ~CefRegistrationImpl() override {
    CEF_REQUIRE_UIT();

    // May be null if OnMediaRouterDestroyed was called.
    if (browser_context_getter_.is_null())
      return;

    auto browser_context = GetBrowserContext(browser_context_getter_);
    if (!browser_context)
      return;

    browser_context->GetMediaRouterManager()->RemoveObserver(this);
  }

  void Initialize(const CefBrowserContext::Getter& browser_context_getter) {
    CEF_REQUIRE_UIT();
    DCHECK(!browser_context_getter.is_null());
    DCHECK(browser_context_getter_.is_null());
    browser_context_getter_ = browser_context_getter;

    auto browser_context = GetBrowserContext(browser_context_getter_);
    if (!browser_context)
      return;

    browser_context->GetMediaRouterManager()->AddObserver(this);
  }

 private:
  // CefMediaRouterManager::Observer methods:
  void OnMediaRouterDestroyed() override { browser_context_getter_.Reset(); }

  void OnMediaSinks(
      const CefMediaRouterManager::MediaSinkVector& sinks) override {
    std::vector<CefRefPtr<CefMediaSink>> cef_sinks;
    for (const auto& sink : sinks) {
      cef_sinks.push_back(new CefMediaSinkImpl(sink.sink));
    }
    observer_->OnSinks(cef_sinks);
  }

  void OnMediaRoutes(
      const CefMediaRouterManager::MediaRouteVector& routes) override {
    std::vector<CefRefPtr<CefMediaRoute>> cef_routes;
    for (const auto& route : routes) {
      cef_routes.push_back(MakeCefRoute(route));
    }
    observer_->OnRoutes(cef_routes);
  }

  void OnMediaRouteMessages(
      const media_router::MediaRoute& route,
      const CefMediaRouterManager::MediaMessageVector& messages) override {
    CefRefPtr<CefMediaRoute> cef_route = MakeCefRoute(route);
    for (const auto& message : messages) {
      if (message->type == media_router::mojom::RouteMessage::Type::TEXT) {
        if (message->message.has_value()) {
          const std::string& str = *(message->message);
          observer_->OnRouteMessageReceived(cef_route, str.c_str(), str.size());
        }
      } else if (message->type ==
                 media_router::mojom::RouteMessage::Type::BINARY) {
        if (message->data.has_value()) {
          const std::vector<uint8_t>& data = *(message->data);
          observer_->OnRouteMessageReceived(cef_route, data.data(),
                                            data.size());
        }
      }
    }
  }

  void OnMediaRouteStateChange(
      const media_router::MediaRoute& route,
      const content::PresentationConnectionStateChangeInfo& info) override {
    observer_->OnRouteStateChanged(MakeCefRoute(route),
                                   ToConnectionState(info.state));
  }

  CefRefPtr<CefMediaRoute> MakeCefRoute(const media_router::MediaRoute& route) {
    return new CefMediaRouteImpl(route, browser_context_getter_);
  }

  static CefMediaObserver::ConnectionState ToConnectionState(
      blink::mojom::PresentationConnectionState state) {
    switch (state) {
      case blink::mojom::PresentationConnectionState::CONNECTING:
        return CEF_MRCS_CONNECTING;
      case blink::mojom::PresentationConnectionState::CONNECTED:
        return CEF_MRCS_CONNECTED;
      case blink::mojom::PresentationConnectionState::CLOSED:
        return CEF_MRCS_CLOSED;
      case blink::mojom::PresentationConnectionState::TERMINATED:
        return CEF_MRCS_TERMINATED;
    }
    NOTREACHED();
    return CEF_MRCS_UNKNOWN;
  }

  CefRefPtr<CefMediaObserver> observer_;
  CefBrowserContext::Getter browser_context_getter_;

  IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefRegistrationImpl);
  DISALLOW_COPY_AND_ASSIGN(CefRegistrationImpl);
};

CefMediaRouterImpl::CefMediaRouterImpl() {
  // Verify that our enum matches Chromium's values.
  static_assert(
      static_cast<int>(CEF_MRCR_TOTAL_COUNT) ==
          static_cast<int>(media_router::RouteRequestResult::TOTAL_COUNT),
      "enum mismatch");
}

void CefMediaRouterImpl::Initialize(
    const CefBrowserContext::Getter& browser_context_getter) {
  CEF_REQUIRE_UIT();
  DCHECK(!browser_context_getter.is_null());
  DCHECK(browser_context_getter_.is_null());
  browser_context_getter_ = browser_context_getter;
}

CefRefPtr<CefRegistration> CefMediaRouterImpl::AddObserver(
    CefRefPtr<CefMediaObserver> observer) {
  if (!observer)
    return nullptr;
  CefRefPtr<CefRegistrationImpl> registration =
      new CefRegistrationImpl(observer);
  InitializeRegistrationOnUIThread(registration);
  return registration.get();
}

CefRefPtr<CefMediaSource> CefMediaRouterImpl::GetSource(const CefString& urn) {
  if (urn.empty())
    return nullptr;

  // Check for a valid URL and supported Cast/DIAL schemes.
  GURL presentation_url(urn.ToString());
  if (!media_router::IsValidPresentationUrl(presentation_url)) {
    return nullptr;
  }

  if (presentation_url.SchemeIsHTTPOrHTTPS()) {
    // We don't support tab/desktop mirroring, which is what Cast uses for
    // arbitrary HTTP/HTTPS URLs (see CastMediaSource).
    return nullptr;
  }

  return new CefMediaSourceImpl(presentation_url);
}

void CefMediaRouterImpl::NotifyCurrentSinks() {
  if (!CEF_CURRENTLY_ON_UIT()) {
    CEF_POST_TASK(
        CEF_UIT, base::BindOnce(&CefMediaRouterImpl::NotifyCurrentSinks, this));
    return;
  }

  auto browser_context = GetBrowserContext(browser_context_getter_);
  if (!browser_context)
    return;

  browser_context->GetMediaRouterManager()->NotifyCurrentSinks();
}

void CefMediaRouterImpl::CreateRoute(
    CefRefPtr<CefMediaSource> source,
    CefRefPtr<CefMediaSink> sink,
    CefRefPtr<CefMediaRouteCreateCallback> callback) {
  if (!CEF_CURRENTLY_ON_UIT()) {
    CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefMediaRouterImpl::CreateRoute,
                                          this, source, sink, callback));
    return;
  }

  std::string error;

  auto browser_context = GetBrowserContext(browser_context_getter_);
  if (!browser_context) {
    error = "Context has already been destroyed";
  } else if (!source || !source->IsValid()) {
    error = "Source is empty or invalid";
  } else if (!sink || !sink->IsValid()) {
    error = "Sink is empty or invalid";
  } else if (!sink->IsCompatibleWith(source)) {
    error = "Sink is not compatible with source";
  }

  if (!error.empty()) {
    LOG(WARNING) << "Media route creation failed: " << error;
    if (callback) {
      callback->OnMediaRouteCreateFinished(CEF_MRCR_UNKNOWN_ERROR, error,
                                           nullptr);
    }
    return;
  }

  auto source_impl = static_cast<CefMediaSourceImpl*>(source.get());
  auto sink_impl = static_cast<CefMediaSinkImpl*>(sink.get());

  browser_context->GetMediaRouterManager()->CreateRoute(
      source_impl->source().id(), sink_impl->sink().id(), url::Origin(),
      base::BindOnce(&CefMediaRouterImpl::CreateRouteCallback, this, callback));
}

void CefMediaRouterImpl::NotifyCurrentRoutes() {
  if (!CEF_CURRENTLY_ON_UIT()) {
    CEF_POST_TASK(CEF_UIT, base::BindOnce(
                               &CefMediaRouterImpl::NotifyCurrentRoutes, this));
    return;
  }

  auto browser_context = GetBrowserContext(browser_context_getter_);
  if (!browser_context)
    return;

  browser_context->GetMediaRouterManager()->NotifyCurrentRoutes();
}

void CefMediaRouterImpl::InitializeRegistrationOnUIThread(
    CefRefPtr<CefRegistrationImpl> registration) {
  if (!CEF_CURRENTLY_ON_UIT()) {
    CEF_POST_TASK(
        CEF_UIT,
        base::BindOnce(&CefMediaRouterImpl::InitializeRegistrationOnUIThread,
                       this, registration));
    return;
  }
  registration->Initialize(browser_context_getter_);
}

void CefMediaRouterImpl::CreateRouteCallback(
    CefRefPtr<CefMediaRouteCreateCallback> callback,
    const media_router::RouteRequestResult& result) {
  CEF_REQUIRE_UIT();

  if (result.result_code() != media_router::RouteRequestResult::OK) {
    LOG(WARNING) << "Media route creation failed: " << result.error() << " ("
                 << result.result_code() << ")";
  }

  if (!callback)
    return;

  CefRefPtr<CefMediaRoute> route;
  if (result.result_code() == media_router::RouteRequestResult::OK &&
      result.route()) {
    route = new CefMediaRouteImpl(*result.route(), browser_context_getter_);
  }

  callback->OnMediaRouteCreateFinished(
      static_cast<cef_media_route_create_result_t>(result.result_code()),
      result.error(), route);
}

// static
CefRefPtr<CefMediaRouter> CefMediaRouter::GetGlobalMediaRouter() {
  return CefRequestContext::GetGlobalContext()->GetMediaRouter();
}
