// Copyright 2018 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/cast_internal_message_util.h"

#include "base/base64url.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/sha1.h"
#include "chrome/common/media_router/discovery/media_sink_internal.h"
#include "chrome/common/media_router/providers/cast/cast_media_source.h"
#include "components/cast_channel/cast_socket.h"
#include "components/cast_channel/proto/cast_channel.pb.h"
#include "net/base/escape.h"

namespace media_router {

namespace {

// The ID for the backdrop app. Cast devices running the backdrop app is
// considered idle, and an active session should not be reported.
constexpr char kBackdropAppId[] = "E8C28D3C";

constexpr char kClientConnect[] = "client_connect";
constexpr char kAppMessage[] = "app_message";
constexpr char kReceiverAction[] = "receiver_action";
constexpr char kNewSession[] = "new_session";
constexpr char kUpdateSession[] = "update_session";

bool GetString(const base::Value& value,
               const std::string& key,
               std::string* out) {
  const base::Value* string_value =
      value.FindKeyOfType(key, base::Value::Type::STRING);
  if (!string_value)
    return false;

  *out = string_value->GetString();
  return !out->empty();
}

void CopyValueWithDefault(const base::Value& from,
                          const std::string& key,
                          base::Value default_value,
                          base::Value* to) {
  const base::Value* value = from.FindKey(key);
  to->SetKey(key, value ? value->Clone() : std::move(default_value));
}

void CopyValue(const base::Value& from,
               const std::string& key,
               base::Value* to) {
  const base::Value* value = from.FindKey(key);
  if (value)
    to->SetKey(key, value->Clone());
}

CastInternalMessage::Type CastInternalMessageTypeFromString(
    const std::string& type) {
  if (type == kClientConnect)
    return CastInternalMessage::Type::kClientConnect;
  if (type == kAppMessage)
    return CastInternalMessage::Type::kAppMessage;
  if (type == kReceiverAction)
    return CastInternalMessage::Type::kReceiverAction;
  if (type == kNewSession)
    return CastInternalMessage::Type::kNewSession;
  if (type == kUpdateSession)
    return CastInternalMessage::Type::kUpdateSession;

  return CastInternalMessage::Type::kOther;
}

std::string CastInternalMessageTypeToString(CastInternalMessage::Type type) {
  switch (type) {
    case CastInternalMessage::Type::kClientConnect:
      return kClientConnect;
    case CastInternalMessage::Type::kAppMessage:
      return kAppMessage;
    case CastInternalMessage::Type::kReceiverAction:
      return kReceiverAction;
    case CastInternalMessage::Type::kNewSession:
      return kNewSession;
    case CastInternalMessage::Type::kUpdateSession:
      return kUpdateSession;
    case CastInternalMessage::Type::kOther:
      NOTREACHED();
      return "";
  }
  NOTREACHED();
  return "";
}

// Possible types in a receiver_action message.
constexpr char kReceiverActionTypeCast[] = "cast";
constexpr char kReceiverActionTypeStop[] = "stop";

base::ListValue CapabilitiesToListValue(uint8_t capabilities) {
  base::ListValue value;
  auto& storage = value.GetList();
  if (capabilities & cast_channel::VIDEO_OUT)
    storage.emplace_back("video_out");
  if (capabilities & cast_channel::VIDEO_IN)
    storage.emplace_back("video_in");
  if (capabilities & cast_channel::AUDIO_OUT)
    storage.emplace_back("audio_out");
  if (capabilities & cast_channel::AUDIO_IN)
    storage.emplace_back("audio_in");
  if (capabilities & cast_channel::MULTIZONE_GROUP)
    storage.emplace_back("multizone_group");
  return value;
}

std::string GetReceiverLabel(const MediaSinkInternal& sink,
                             const std::string& hash_token) {
  std::string label = base::SHA1HashString(sink.sink().id() + hash_token);
  base::Base64UrlEncode(label, base::Base64UrlEncodePolicy::OMIT_PADDING,
                        &label);
  return label;
}

base::Value CreateReceiver(const MediaSinkInternal& sink,
                           const std::string& hash_token) {
  base::Value receiver(base::Value::Type::DICTIONARY);

  if (!hash_token.empty()) {
    receiver.SetKey("label", base::Value(GetReceiverLabel(sink, hash_token)));
  }

  receiver.SetKey("friendlyName",
                  base::Value(net::EscapeForHTML(sink.sink().name())));
  receiver.SetKey("capabilities",
                  CapabilitiesToListValue(sink.cast_data().capabilities));
  receiver.SetKey("volume", base::Value());
  receiver.SetKey("isActiveInput", base::Value());
  receiver.SetKey("displayStatus", base::Value());

  receiver.SetKey("receiverType", base::Value("cast"));
  return receiver;
}

base::Value CreateReceiverActionMessage(const std::string& client_id,
                                        const MediaSinkInternal& sink,
                                        const std::string& hash_token,
                                        const char* action_type) {
  base::Value message(base::Value::Type::DICTIONARY);
  message.SetKey("receiver", CreateReceiver(sink, hash_token));
  message.SetKey("action", base::Value(action_type));

  base::Value value(base::Value::Type::DICTIONARY);
  value.SetKey("type", base::Value(CastInternalMessageTypeToString(
                           CastInternalMessage::Type::kReceiverAction)));
  value.SetKey("message", std::move(message));
  value.SetKey("sequenceNumber", base::Value(-1));
  value.SetKey("timeoutMillis", base::Value(0));
  value.SetKey("clientId", base::Value(client_id));
  return value;
}

base::Value CreateAppMessageBody(
    const std::string& session_id,
    const cast_channel::CastMessage& cast_message) {
  // TODO(https://crbug.com/862532): Investigate whether it is possible to move
  // instead of copying the contents of |cast_message|. Right now copying is
  // done because the message is passed as a const ref at the
  // CastSocket::Observer level.
  base::Value message(base::Value::Type::DICTIONARY);
  message.SetKey("sessionId", base::Value(session_id));
  message.SetKey("namespaceName", base::Value(cast_message.namespace_()));
  switch (cast_message.payload_type()) {
    case cast_channel::CastMessage_PayloadType_STRING:
      message.SetKey("message", base::Value(cast_message.payload_utf8()));
      break;
    case cast_channel::CastMessage_PayloadType_BINARY: {
      const auto& payload = cast_message.payload_binary();
      message.SetKey("message",
                     base::Value(base::Value::BlobStorage(
                         payload.front(), payload.front() + payload.size())));
      break;
    }
    default:
      NOTREACHED();
      break;
  }
  return message;
}

blink::mojom::PresentationConnectionMessagePtr CreatePresentationMessage(
    const base::Value& message) {
  std::string message_str;
  CHECK(base::JSONWriter::Write(message, &message_str));
  return blink::mojom::PresentationConnectionMessage::NewMessage(message_str);
}

// Creates a message with a session value in the "message" field. |type| must
// be either kNewSession or kUpdateSession.
blink::mojom::PresentationConnectionMessagePtr CreateSessionMessage(
    const CastSession& session,
    const std::string& client_id,
    const MediaSinkInternal& sink,
    const std::string& hash_token,
    CastInternalMessage::Type type) {
  DCHECK(type == CastInternalMessage::Type::kNewSession ||
         type == CastInternalMessage::Type::kUpdateSession);
  base::Value message(base::Value::Type::DICTIONARY);
  message.SetKey("type", base::Value(CastInternalMessageTypeToString(type)));
  base::Value session_with_receiver_label = session.value().Clone();
  DCHECK(!session_with_receiver_label.FindPath({"receiver", "label"}));
  session_with_receiver_label.SetPath(
      {"receiver", "label"}, base::Value(GetReceiverLabel(sink, hash_token)));
  message.SetKey("message", std::move(session_with_receiver_label));
  message.SetKey("sequenceNumber", base::Value(-1));
  message.SetKey("timeoutMillis", base::Value(0));
  message.SetKey("clientId", base::Value(client_id));
  return CreatePresentationMessage(message);
}

}  // namespace

// static
std::unique_ptr<CastInternalMessage> CastInternalMessage::From(
    base::Value message) {
  if (!message.is_dict()) {
    DVLOG(2) << "Failed to read JSON message: " << message;
    return nullptr;
  }

  std::string str_type;
  if (!GetString(message, "type", &str_type)) {
    DVLOG(2) << "Missing type value, message: " << message;
    return nullptr;
  }

  CastInternalMessage::Type message_type =
      CastInternalMessageTypeFromString(str_type);
  if (message_type == CastInternalMessage::Type::kOther) {
    DVLOG(2) << __func__ << ": Unsupported message type: " << str_type
             << ", message: " << message;
    return nullptr;
  }

  std::string client_id;
  if (!GetString(message, "clientId", &client_id)) {
    DVLOG(2) << "Missing clientId, message: " << message;
    return nullptr;
  }

  base::Value* message_body_value = message.FindKey("message");
  if (!message_body_value ||
      (!message_body_value->is_dict() && !message_body_value->is_string())) {
    DVLOG(2) << "Missing message body, message: " << message;
    return nullptr;
  }

  auto internal_message =
      std::make_unique<CastInternalMessage>(message_type, client_id);

  base::Value* sequence_number_value =
      message.FindKeyOfType("sequenceNumber", base::Value::Type::INTEGER);
  if (sequence_number_value)
    internal_message->sequence_number = sequence_number_value->GetInt();

  if (message_type == CastInternalMessage::Type::kAppMessage) {
    if (!message_body_value->is_dict())
      return nullptr;

    if (!GetString(*message_body_value, "namespaceName",
                   &internal_message->app_message_namespace) ||
        !GetString(*message_body_value, "sessionId",
                   &internal_message->app_message_session_id)) {
      DVLOG(2) << "Missing namespace or session ID, message: " << message;
      return nullptr;
    }

    base::Value* app_message_value = message_body_value->FindKey("message");
    if (!app_message_value ||
        (!app_message_value->is_dict() && !app_message_value->is_string())) {
      DVLOG(2) << "Missing app message, message: " << message;
      return nullptr;
    }
    internal_message->app_message_body = std::move(*app_message_value);
  }

  return internal_message;
}

CastInternalMessage::CastInternalMessage(CastInternalMessage::Type type,
                                         const std::string& client_id)
    : type(type), client_id(client_id) {}

CastInternalMessage::~CastInternalMessage() = default;

blink::mojom::PresentationConnectionMessagePtr CreateReceiverActionCastMessage(
    const std::string& client_id,
    const MediaSinkInternal& sink,
    const std::string& hash_token) {
  return CreatePresentationMessage(CreateReceiverActionMessage(
      client_id, sink, hash_token, kReceiverActionTypeCast));
}

blink::mojom::PresentationConnectionMessagePtr CreateReceiverActionStopMessage(
    const std::string& client_id,
    const MediaSinkInternal& sink,
    const std::string& hash_token) {
  return CreatePresentationMessage(CreateReceiverActionMessage(
      client_id, sink, hash_token, kReceiverActionTypeStop));
}

// static
std::unique_ptr<CastSession> CastSession::From(
    const MediaSinkInternal& sink,
    const base::Value& receiver_status) {
  // There should be only 1 app on |receiver_status|.
  const base::Value* app_list_value =
      receiver_status.FindKeyOfType("applications", base::Value::Type::LIST);
  if (!app_list_value || app_list_value->GetList().size() != 1) {
    DVLOG(2) << "receiver_status does not contain exactly one app: "
             << receiver_status;
    return nullptr;
  }

  auto session = std::make_unique<CastSession>();

  // Fill in mandatory Session fields.
  const base::Value& app_value = app_list_value->GetList()[0];
  if (!GetString(app_value, "sessionId", &session->session_id_) ||
      !GetString(app_value, "appId", &session->app_id_) ||
      !GetString(app_value, "transportId", &session->transport_id_) ||
      !GetString(app_value, "displayName", &session->display_name_)) {
    DVLOG(2) << "app_value missing mandatory fields: " << app_value;
    return nullptr;
  }

  if (session->app_id_ == kBackdropAppId) {
    DVLOG(2) << sink.sink().id() << " is running the backdrop app";
    return nullptr;
  }

  // Optional Session fields.
  GetString(app_value, "statusText", &session->status_);

  // The receiver label will be populated by each profile using
  // |session->value|.
  base::Value receiver_value = CreateReceiver(sink, std::string());
  CopyValue(receiver_status, "volume", &receiver_value);
  CopyValue(receiver_status, "isActiveInput", &receiver_value);

  // Create |session->value|.
  session->value_ = base::Value(base::Value::Type::DICTIONARY);
  auto& session_value = session->value_;
  session_value.SetKey("sessionId", base::Value(session->session_id()));
  session_value.SetKey("appId", base::Value(session->app_id()));
  session_value.SetKey("transportId", base::Value(session->transport_id()));
  session_value.SetKey("receiver", std::move(receiver_value));

  CopyValueWithDefault(app_value, "displayName", base::Value(""),
                       &session_value);
  CopyValueWithDefault(app_value, "senderApps", base::ListValue(),
                       &session_value);
  CopyValueWithDefault(app_value, "statusText", base::Value(), &session_value);
  CopyValueWithDefault(app_value, "appImages", base::ListValue(),
                       &session_value);

  const base::Value* namespaces_value =
      app_value.FindKeyOfType("namespaces", base::Value::Type::LIST);
  if (!namespaces_value || namespaces_value->GetList().empty()) {
    // A session without namespaces is invalid, except for a multizone leader.
    if (session->app_id() != kMultizoneLeaderAppId)
      return nullptr;
  } else {
    for (const auto& namespace_value : namespaces_value->GetList()) {
      std::string message_namespace;
      if (!namespace_value.is_dict() ||
          !GetString(namespace_value, "name", &message_namespace))
        return nullptr;

      session->message_namespaces_.insert(std::move(message_namespace));
    }
  }
  session_value.SetKey("namespaces",
                       namespaces_value ? namespaces_value->Clone()
                                        : base::Value(base::Value::Type::LIST));
  return session;
}

CastSession::CastSession() = default;
CastSession::~CastSession() = default;

std::string CastSession::GetRouteDescription() const {
  return !status_.empty() ? status_ : display_name_;
}

void CastSession::UpdateSession(std::unique_ptr<CastSession> from) {
  status_ = std::move(from->status_);
  message_namespaces_ = std::move(from->message_namespaces_);

  auto* status_text_value = from->value_.FindKey("statusText");
  DCHECK(status_text_value);
  value_.SetKey("statusText", std::move(*status_text_value));
  auto* namespaces_value = from->value_.FindKey("namespaces");
  DCHECK(namespaces_value);
  value_.SetKey("namespaces", std::move(*namespaces_value));
  auto* receiver_volume_value = from->value_.FindPath({"receiver", "volume"});
  DCHECK(receiver_volume_value);
  value_.SetPath({"receiver", "volume"}, std::move(*receiver_volume_value));
}

blink::mojom::PresentationConnectionMessagePtr CreateNewSessionMessage(
    const CastSession& session,
    const std::string& client_id,
    const MediaSinkInternal& sink,
    const std::string& hash_token) {
  return CreateSessionMessage(session, client_id, sink, hash_token,
                              CastInternalMessage::Type::kNewSession);
}

blink::mojom::PresentationConnectionMessagePtr CreateUpdateSessionMessage(
    const CastSession& session,
    const std::string& client_id,
    const MediaSinkInternal& sink,
    const std::string& hash_token) {
  return CreateSessionMessage(session, client_id, sink, hash_token,
                              CastInternalMessage::Type::kUpdateSession);
}

blink::mojom::PresentationConnectionMessagePtr CreateAppMessageAck(
    const std::string& client_id,
    int sequence_number) {
  base::Value message(base::Value::Type::DICTIONARY);
  message.SetKey("type", base::Value(CastInternalMessageTypeToString(
                             CastInternalMessage::Type::kAppMessage)));
  message.SetKey("message", base::Value());
  message.SetKey("sequenceNumber", base::Value(sequence_number));
  message.SetKey("timeoutMillis", base::Value(0));
  message.SetKey("clientId", base::Value(client_id));
  return CreatePresentationMessage(message);
}

blink::mojom::PresentationConnectionMessagePtr CreateAppMessage(
    const std::string& session_id,
    const std::string& client_id,
    const cast_channel::CastMessage& cast_message) {
  base::Value message(base::Value::Type::DICTIONARY);
  message.SetKey("type", base::Value(CastInternalMessageTypeToString(
                             CastInternalMessage::Type::kAppMessage)));
  message.SetKey("message", CreateAppMessageBody(session_id, cast_message));
  message.SetKey("sequenceNumber", base::Value(-1));
  message.SetKey("timeoutMillis", base::Value(0));
  message.SetKey("clientId", base::Value(client_id));
  return CreatePresentationMessage(message);
}

}  // namespace media_router
