// Copyright 2019 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/providers/cast/app_activity.h"

#include <algorithm>
#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/containers/contains.h"
#include "chrome/browser/media/router/providers/cast/cast_activity_manager.h"
#include "chrome/browser/media/router/providers/cast/cast_session_client.h"
#include "components/cast_channel/enum_table.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/origin.h"

using blink::mojom::PresentationConnectionCloseReason;
using blink::mojom::PresentationConnectionMessagePtr;

namespace media_router {

AppActivity::AppActivity(const MediaRoute& route,
                         const std::string& app_id,
                         cast_channel::CastMessageHandler* message_handler,
                         CastSessionTracker* session_tracker)
    : CastActivity(route, app_id, message_handler, session_tracker) {}

AppActivity::~AppActivity() = default;

void AppActivity::OnSessionSet(const CastSession& session) {
  if (media_controller_)
    media_controller_->SetSession(session);
}

void AppActivity::OnSessionUpdated(const CastSession& session,
                                   const std::string& hash_token) {
  for (auto& client : connected_clients_) {
    client.second->SendMessageToClient(
        CreateUpdateSessionMessage(session, client.first, sink_, hash_token));
  }
  if (media_controller_)
    media_controller_->SetSession(session);
}

cast_channel::Result AppActivity::SendAppMessageToReceiver(
    const CastInternalMessage& cast_message) {
  CastSessionClient* client = GetClient(cast_message.client_id());
  const CastSession* session = GetSession();
  if (!session) {
    if (client && cast_message.sequence_number()) {
      client->SendErrorCodeToClient(
          *cast_message.sequence_number(),
          CastInternalMessage::ErrorCode::kSessionError,
          "Invalid session ID: " + session_id_.value_or("<missing>"));
    }

    return cast_channel::Result::kFailed;
  }
  const std::string& message_namespace = cast_message.app_message_namespace();
  if (!base::Contains(session->message_namespaces(), message_namespace)) {
    DLOG(ERROR) << "Disallowed message namespace: " << message_namespace;
    if (client && cast_message.sequence_number()) {
      client->SendErrorCodeToClient(
          *cast_message.sequence_number(),
          CastInternalMessage::ErrorCode::kInvalidParameter,
          "Invalid namespace: " + message_namespace);
    }
    return cast_channel::Result::kFailed;
  }
  return message_handler_->SendAppMessage(
      cast_channel_id(),
      cast_channel::CreateCastMessage(
          message_namespace, cast_message.app_message_body(),
          cast_message.client_id(), session->transport_id()));
}

absl::optional<int> AppActivity::SendMediaRequestToReceiver(
    const CastInternalMessage& cast_message) {
  CastSession* session = GetSession();
  if (!session)
    return absl::nullopt;
  return message_handler_->SendMediaRequest(
      cast_channel_id(), cast_message.v2_message_body(),
      cast_message.client_id(), session->transport_id());
}

void AppActivity::SendSetVolumeRequestToReceiver(
    const CastInternalMessage& cast_message,
    cast_channel::ResultCallback callback) {
  message_handler_->SendSetVolumeRequest(
      cast_channel_id(), cast_message.v2_message_body(),
      cast_message.client_id(), std::move(callback));
}

void AppActivity::SendMediaStatusToClients(const base::Value& media_status,
                                           absl::optional<int> request_id) {
  CastActivity::SendMediaStatusToClients(media_status, request_id);
  if (media_controller_)
    media_controller_->SetMediaStatus(media_status);
}

void AppActivity::CreateMediaController(
    mojo::PendingReceiver<mojom::MediaController> media_controller,
    mojo::PendingRemote<mojom::MediaStatusObserver> observer) {
  media_controller_ = std::make_unique<CastMediaController>(
      this, std::move(media_controller), std::move(observer));

  if (session_id_) {
    CastSession* session = GetSession();
    if (session) {
      media_controller_->SetSession(*session);
      base::Value status_request(base::Value::Type::DICTIONARY);
      status_request.SetStringKey(
          "type", cast_util::EnumToString<
                      cast_channel::V2MessageType,
                      cast_channel::V2MessageType::kMediaGetStatus>());
      message_handler_->SendMediaRequest(cast_channel_id(), status_request,
                                         media_controller_->sender_id(),
                                         session->transport_id());
    }
  }
}

void AppActivity::OnAppMessage(const cast::channel::CastMessage& message) {
  if (!session_id_) {
    DVLOG(2) << "No session associated with activity!";
    return;
  }

  const std::string& client_id = message.destination_id();
  if (client_id == "*") {
    for (const auto& client : connected_clients_) {
      SendMessageToClient(
          client.first, CreateAppMessage(*session_id_, client.first, message));
    }
  } else {
    SendMessageToClient(client_id,
                        CreateAppMessage(*session_id_, client_id, message));
  }
}

void AppActivity::OnInternalMessage(
    const cast_channel::InternalMessage& message) {}

bool AppActivity::CanJoinSession(const CastMediaSource& cast_source,
                                 bool off_the_record) const {
  if (!cast_source.ContainsApp(app_id()))
    return false;

  if (base::Contains(connected_clients_, cast_source.client_id()))
    return false;

  if (route().is_off_the_record() != off_the_record)
    return false;

  return true;
}

bool AppActivity::HasJoinableClient(AutoJoinPolicy policy,
                                    const url::Origin& origin,
                                    int tab_id) const {
  return std::any_of(connected_clients_.begin(), connected_clients_.end(),
                     [policy, &origin, tab_id](const auto& client) {
                       return IsAutoJoinAllowed(policy, origin, tab_id,
                                                client.second->origin(),
                                                client.second->tab_id());
                     });
}

}  // namespace media_router
