// Copyright 2015 The Chromium 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 "chrome/browser/media/router/media_router_base.h"

#include <memory>

#include "base/bind.h"
#include "base/guid.h"
#include "base/stl_util.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/media/router/mojo/media_route_controller.h"
#endif  // !defined(OS_ANDROID)

using blink::mojom::PresentationConnectionState;

namespace media_router {

// A MediaRoutesObserver that maintains state about the current set of media
// routes.
class MediaRouterBase::InternalMediaRoutesObserver
    : public MediaRoutesObserver {
 public:
  explicit InternalMediaRoutesObserver(MediaRouter* router)
      : MediaRoutesObserver(router), has_route(false) {}
  ~InternalMediaRoutesObserver() override {}

  // MediaRoutesObserver
  void OnRoutesUpdated(
      const std::vector<MediaRoute>& routes,
      const std::vector<MediaRoute::Id>& joinable_route_ids) override {
    current_routes = routes;
    incognito_route_ids.clear();
    // TODO(crbug.com/611486): Have the MRPM pass a list of joinable route ids
    // via |joinable_route_ids|, and check here if it is non-empty.
    has_route = !routes.empty();
    for (const auto& route : routes) {
      if (route.is_incognito())
        incognito_route_ids.push_back(route.media_route_id());
    }
  }

  bool has_route;
  std::vector<MediaRoute> current_routes;
  std::vector<MediaRoute::Id> incognito_route_ids;

 private:
  DISALLOW_COPY_AND_ASSIGN(InternalMediaRoutesObserver);
};

MediaRouterBase::~MediaRouterBase() {
  CHECK(!internal_routes_observer_);
}

std::unique_ptr<PresentationConnectionStateSubscription>
MediaRouterBase::AddPresentationConnectionStateChangedCallback(
    const MediaRoute::Id& route_id,
    const content::PresentationConnectionStateChangedCallback& callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  auto& callbacks = presentation_connection_state_callbacks_[route_id];
  if (!callbacks) {
    callbacks = std::make_unique<PresentationConnectionStateChangedCallbacks>();
    callbacks->set_removal_callback(base::Bind(
        &MediaRouterBase::OnPresentationConnectionStateCallbackRemoved,
        base::Unretained(this), route_id));
  }

  return callbacks->Add(callback);
}

void MediaRouterBase::OnIncognitoProfileShutdown() {
  for (const auto& route_id : internal_routes_observer_->incognito_route_ids)
    TerminateRoute(route_id);
}

IssueManager* MediaRouterBase::GetIssueManager() {
  return &issue_manager_;
}

std::vector<MediaRoute> MediaRouterBase::GetCurrentRoutes() const {
  return internal_routes_observer_->current_routes;
}

std::unique_ptr<media::MediaController> MediaRouterBase::GetMediaController(
    const MediaRoute::Id& route_id) {
  return nullptr;
}

#if !defined(OS_ANDROID)
scoped_refptr<MediaRouteController> MediaRouterBase::GetRouteController(
    const MediaRoute::Id& route_id) {
  return nullptr;
}
#endif  // !defined(OS_ANDROID)

MediaRouterBase::MediaRouterBase() : initialized_(false) {}

// static
std::string MediaRouterBase::CreatePresentationId() {
  return "mr_" + base::GenerateGUID();
}

void MediaRouterBase::NotifyPresentationConnectionStateChange(
    const MediaRoute::Id& route_id,
    PresentationConnectionState state) {
  // We should call NotifyPresentationConnectionClose() for the CLOSED state.
  DCHECK_NE(state, PresentationConnectionState::CLOSED);

  auto it = presentation_connection_state_callbacks_.find(route_id);
  if (it == presentation_connection_state_callbacks_.end())
    return;

  it->second->Notify(content::PresentationConnectionStateChangeInfo(state));
}

void MediaRouterBase::NotifyPresentationConnectionClose(
    const MediaRoute::Id& route_id,
    blink::mojom::PresentationConnectionCloseReason reason,
    const std::string& message) {
  auto it = presentation_connection_state_callbacks_.find(route_id);
  if (it == presentation_connection_state_callbacks_.end())
    return;

  content::PresentationConnectionStateChangeInfo info(
      PresentationConnectionState::CLOSED);
  info.close_reason = reason;
  info.message = message;
  it->second->Notify(info);
}

bool MediaRouterBase::HasJoinableRoute() const {
  return internal_routes_observer_->has_route;
}

const MediaRoute* MediaRouterBase::GetRoute(
    const MediaRoute::Id& route_id) const {
  const auto& routes = internal_routes_observer_->current_routes;
  auto it = std::find_if(routes.begin(), routes.end(),
                         [&route_id](const MediaRoute& route) {
                           return route.media_route_id() == route_id;
                         });
  return it == routes.end() ? nullptr : &*it;
}

void MediaRouterBase::Initialize() {
  DCHECK(!initialized_);
  // The observer calls virtual methods on MediaRouter; it must be created
  // outside of the ctor
  internal_routes_observer_.reset(new InternalMediaRoutesObserver(this));
  initialized_ = true;
}

void MediaRouterBase::OnPresentationConnectionStateCallbackRemoved(
    const MediaRoute::Id& route_id) {
  auto it = presentation_connection_state_callbacks_.find(route_id);
  if (it != presentation_connection_state_callbacks_.end() &&
      it->second->empty()) {
    presentation_connection_state_callbacks_.erase(route_id);
  }
}

void MediaRouterBase::Shutdown() {
  // The observer calls virtual methods on MediaRouter; it must be destroyed
  // outside of the dtor
  internal_routes_observer_.reset();
}

#if !defined(OS_ANDROID)
void MediaRouterBase::DetachRouteController(const MediaRoute::Id& route_id,
                                            MediaRouteController* controller) {}
#endif  // !defined(OS_ANDROID)

void MediaRouterBase::RegisterRemotingSource(
    SessionID tab_id,
    CastRemotingConnector* remoting_source) {
  auto it = remoting_sources_.find(tab_id);
  if (it != remoting_sources_.end()) {
    DCHECK(remoting_source == it->second);
    return;
  }
  remoting_sources_.emplace(tab_id, remoting_source);
}

void MediaRouterBase::UnregisterRemotingSource(SessionID tab_id) {
  auto it = remoting_sources_.find(tab_id);
  DCHECK(it != remoting_sources_.end());
  remoting_sources_.erase(it);
}

base::Value MediaRouterBase::GetState() const {
  NOTREACHED() << "Should not invoke MediaRouterBase::GetState()";
  return base::Value(base::Value::Type::DICTIONARY);
}

}  // namespace media_router
