// Copyright 2013 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 "cobalt/media/blink/webcontentdecryptionmodulesession_impl.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "cobalt/media/base/cdm_key_information.h"
#include "cobalt/media/base/cdm_promise.h"
#include "cobalt/media/base/key_system_names.h"
#include "cobalt/media/base/key_systems.h"
#include "cobalt/media/base/limits.h"
#include "cobalt/media/base/media_keys.h"
#include "cobalt/media/blink/cdm_result_promise.h"
#include "cobalt/media/blink/cdm_session_adapter.h"
#include "cobalt/media/blink/webmediaplayer_util.h"
#include "cobalt/media/cdm/json_web_key.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebEncryptedMediaKeyInformation.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/platform/WebVector.h"

#if defined(USE_PROPRIETARY_CODECS)
#include "cobalt/media/cdm/cenc_utils.h"
#endif

namespace cobalt {
namespace media {

const char kCloseSessionUMAName[] = "CloseSession";
const char kGenerateRequestUMAName[] = "GenerateRequest";
const char kLoadSessionUMAName[] = "LoadSession";
const char kRemoveSessionUMAName[] = "RemoveSession";
const char kUpdateSessionUMAName[] = "UpdateSession";

static blink::WebContentDecryptionModuleSession::Client::MessageType
convertMessageType(MediaKeys::MessageType message_type) {
  switch (message_type) {
    case media::MediaKeys::LICENSE_REQUEST:
      return blink::WebContentDecryptionModuleSession::Client::MessageType::
          LicenseRequest;
    case media::MediaKeys::LICENSE_RENEWAL:
      return blink::WebContentDecryptionModuleSession::Client::MessageType::
          LicenseRenewal;
    case media::MediaKeys::LICENSE_RELEASE:
      return blink::WebContentDecryptionModuleSession::Client::MessageType::
          LicenseRelease;
  }

  NOTREACHED();
  return blink::WebContentDecryptionModuleSession::Client::MessageType::
      LicenseRequest;
}

static blink::WebEncryptedMediaKeyInformation::KeyStatus convertStatus(
    media::CdmKeyInformation::KeyStatus status) {
  switch (status) {
    case media::CdmKeyInformation::USABLE:
      return blink::WebEncryptedMediaKeyInformation::KeyStatus::Usable;
    case media::CdmKeyInformation::INTERNAL_ERROR:
      return blink::WebEncryptedMediaKeyInformation::KeyStatus::InternalError;
    case media::CdmKeyInformation::EXPIRED:
      return blink::WebEncryptedMediaKeyInformation::KeyStatus::Expired;
    case media::CdmKeyInformation::OUTPUT_RESTRICTED:
      return blink::WebEncryptedMediaKeyInformation::KeyStatus::
          OutputRestricted;
    case media::CdmKeyInformation::OUTPUT_DOWNSCALED:
      return blink::WebEncryptedMediaKeyInformation::KeyStatus::
          OutputDownscaled;
    case media::CdmKeyInformation::KEY_STATUS_PENDING:
      return blink::WebEncryptedMediaKeyInformation::KeyStatus::StatusPending;
    case media::CdmKeyInformation::RELEASED:
      return blink::WebEncryptedMediaKeyInformation::KeyStatus::Released;
  }

  NOTREACHED();
  return blink::WebEncryptedMediaKeyInformation::KeyStatus::InternalError;
}

static MediaKeys::SessionType convertSessionType(
    blink::WebEncryptedMediaSessionType session_type) {
  switch (session_type) {
    case blink::WebEncryptedMediaSessionType::Temporary:
      return MediaKeys::TEMPORARY_SESSION;
    case blink::WebEncryptedMediaSessionType::PersistentLicense:
      return MediaKeys::PERSISTENT_LICENSE_SESSION;
    case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage:
      return MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION;
    case blink::WebEncryptedMediaSessionType::Unknown:
      break;
  }

  NOTREACHED();
  return MediaKeys::TEMPORARY_SESSION;
}

static bool SanitizeInitData(EmeInitDataType init_data_type,
                             const unsigned char* init_data,
                             size_t init_data_length,
                             std::vector<uint8_t>* sanitized_init_data,
                             std::string* error_message) {
  DCHECK_GT(init_data_length, 0u);
  if (init_data_length > limits::kMaxInitDataLength) {
    error_message->assign("Initialization data too long.");
    return false;
  }

  switch (init_data_type) {
    case EmeInitDataType::WEBM:
      // |init_data| for WebM is a single key.
      if (init_data_length > limits::kMaxKeyIdLength) {
        error_message->assign("Initialization data for WebM is too long.");
        return false;
      }
      sanitized_init_data->assign(init_data, init_data + init_data_length);
      return true;

    case EmeInitDataType::CENC:
#if defined(USE_PROPRIETARY_CODECS)
      sanitized_init_data->assign(init_data, init_data + init_data_length);
      if (!ValidatePsshInput(*sanitized_init_data)) {
        error_message->assign("Initialization data for CENC is incorrect.");
        return false;
      }
      return true;
#else
      error_message->assign("Initialization data type CENC is not supported.");
      return false;
#endif

    case EmeInitDataType::KEYIDS: {
      // Extract the keys and then rebuild the message. This ensures that any
      // extra data in the provided JSON is dropped.
      std::string init_data_string(init_data, init_data + init_data_length);
      KeyIdList key_ids;
      if (!ExtractKeyIdsFromKeyIdsInitData(init_data_string, &key_ids,
                                           error_message))
        return false;

      for (const auto& key_id : key_ids) {
        if (key_id.size() < limits::kMinKeyIdLength ||
            key_id.size() > limits::kMaxKeyIdLength) {
          error_message->assign("Incorrect key size.");
          return false;
        }
      }

      CreateKeyIdsInitData(key_ids, sanitized_init_data);
      return true;
    }

    case EmeInitDataType::UNKNOWN:
      break;
  }

  NOTREACHED();
  error_message->assign("Initialization data type is not supported.");
  return false;
}

static bool SanitizeSessionId(const blink::WebString& session_id,
                              std::string* sanitized_session_id) {
  // The user agent should thoroughly validate the sessionId value before
  // passing it to the CDM. At a minimum, this should include checking that
  // the length and value (e.g. alphanumeric) are reasonable.
  if (!base::IsStringASCII(session_id)) return false;

  sanitized_session_id->assign(
      base::UTF16ToASCII(base::StringPiece16(session_id)));
  if (sanitized_session_id->length() > limits::kMaxSessionIdLength)
    return false;

  for (const char c : *sanitized_session_id) {
    if (!base::IsAsciiAlpha(c) && !base::IsAsciiDigit(c)) return false;
  }

  return true;
}

static bool SanitizeResponse(const std::string& key_system,
                             const uint8_t* response, size_t response_length,
                             std::vector<uint8_t>* sanitized_response) {
  // The user agent should thoroughly validate the response before passing it
  // to the CDM. This may include verifying values are within reasonable limits,
  // stripping irrelevant data or fields, pre-parsing it, sanitizing it,
  // and/or generating a fully sanitized version. The user agent should check
  // that the length and values of fields are reasonable. Unknown fields should
  // be rejected or removed.
  if (response_length > limits::kMaxSessionResponseLength) return false;

  if (IsClearKey(key_system) || IsExternalClearKey(key_system)) {
    std::string key_string(response, response + response_length);
    KeyIdAndKeyPairs keys;
    MediaKeys::SessionType session_type = MediaKeys::TEMPORARY_SESSION;
    if (!ExtractKeysFromJWKSet(key_string, &keys, &session_type)) return false;

    // Must contain at least one key.
    if (keys.empty()) return false;

    for (const auto key_pair : keys) {
      if (key_pair.first.size() < limits::kMinKeyIdLength ||
          key_pair.first.size() > limits::kMaxKeyIdLength) {
        return false;
      }
    }

    std::string sanitized_data = GenerateJWKSet(keys, session_type);
    sanitized_response->assign(sanitized_data.begin(), sanitized_data.end());
    return true;
  }

  // TODO(jrummell): Verify responses for Widevine.
  sanitized_response->assign(response, response + response_length);
  return true;
}

WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
    const scoped_refptr<CdmSessionAdapter>& adapter)
    : adapter_(adapter), is_closed_(false), weak_ptr_factory_(this) {}

WebContentDecryptionModuleSessionImpl::
    ~WebContentDecryptionModuleSessionImpl() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!session_id_.empty()) adapter_->UnregisterSession(session_id_);
}

void WebContentDecryptionModuleSessionImpl::setClientInterface(Client* client) {
  client_ = client;
}

blink::WebString WebContentDecryptionModuleSessionImpl::sessionId() const {
  return blink::WebString::fromUTF8(session_id_);
}

void WebContentDecryptionModuleSessionImpl::initializeNewSession(
    blink::WebEncryptedMediaInitDataType init_data_type,
    const unsigned char* init_data, size_t init_data_length,
    blink::WebEncryptedMediaSessionType session_type,
    blink::WebContentDecryptionModuleResult result) {
  DCHECK(init_data);
  DCHECK(session_id_.empty());
  DCHECK(thread_checker_.CalledOnValidThread());

  // From https://w3c.github.io/encrypted-media/#generateRequest.
  // 5. If the Key System implementation represented by this object's cdm
  //    implementation value does not support initDataType as an Initialization
  //    Data Type, return a promise rejected with a new DOMException whose name
  //    is NotSupportedError. String comparison is case-sensitive.
  EmeInitDataType eme_init_data_type = ConvertToEmeInitDataType(init_data_type);
  if (!IsSupportedKeySystemWithInitDataType(adapter_->GetKeySystem(),
                                            eme_init_data_type)) {
    std::string message =
        "The initialization data type is not supported by the key system.";
    result.completeWithError(
        blink::WebContentDecryptionModuleExceptionNotSupportedError, 0,
        blink::WebString::fromUTF8(message));
    return;
  }

  // 9.1 If the init data is not valid for initDataType, reject promise with a
  //     new DOMException whose name is InvalidAccessError.
  // 9.2 Let sanitized init data be a validated and sanitized version of init
  //     data. The user agent must thoroughly validate the Initialization Data
  //     before passing it to the CDM. This includes verifying that the length
  //     and values of fields are reasonable, verifying that values are within
  //     reasonable limits, and stripping irrelevant, unsupported, or unknown
  //     data or fields. It is recommended that user agents pre-parse, sanitize,
  //     and/or generate a fully sanitized version of the Initialization Data.
  //     If the Initialization Data format specified by initDataType support
  //     multiple entries, the user agent should remove entries that are not
  //     needed by the CDM.
  // 9.3 If the previous step failed, reject promise with a new DOMException
  //     whose name is InvalidAccessError.
  std::vector<uint8_t> sanitized_init_data;
  std::string message;
  if (!SanitizeInitData(eme_init_data_type, init_data, init_data_length,
                        &sanitized_init_data, &message)) {
    result.completeWithError(
        blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0,
        blink::WebString::fromUTF8(message));
    return;
  }

  // 9.4 Let session id be the empty string.
  //     (Done in constructor.)

  // 9.5 Let message be null.
  //     (Done by CDM.)

  // 9.6 Let cdm be the CDM instance represented by this object's cdm
  //     instance value.
  // 9.7 Use the cdm to execute the following steps:
  adapter_->InitializeNewSession(
      eme_init_data_type, sanitized_init_data, convertSessionType(session_type),
      std::unique_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise(
          result, adapter_->GetKeySystemUMAPrefix() + kGenerateRequestUMAName,
          base::Bind(
              &WebContentDecryptionModuleSessionImpl::OnSessionInitialized,
              weak_ptr_factory_.GetWeakPtr()))));
}

void WebContentDecryptionModuleSessionImpl::load(
    const blink::WebString& session_id,
    blink::WebContentDecryptionModuleResult result) {
  DCHECK(!session_id.isEmpty());
  DCHECK(session_id_.empty());
  DCHECK(thread_checker_.CalledOnValidThread());

  std::string sanitized_session_id;
  if (!SanitizeSessionId(session_id, &sanitized_session_id)) {
    result.completeWithError(
        blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0,
        "Invalid session ID.");
    return;
  }

  // TODO(jrummell): Now that there are 2 types of persistent sessions, the
  // session type should be passed from blink. Type should also be passed in the
  // constructor (and removed from initializeNewSession()).
  adapter_->LoadSession(
      MediaKeys::PERSISTENT_LICENSE_SESSION, sanitized_session_id,
      std::unique_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise(
          result, adapter_->GetKeySystemUMAPrefix() + kLoadSessionUMAName,
          base::Bind(
              &WebContentDecryptionModuleSessionImpl::OnSessionInitialized,
              weak_ptr_factory_.GetWeakPtr()))));
}

void WebContentDecryptionModuleSessionImpl::update(
    const uint8_t* response, size_t response_length,
    blink::WebContentDecryptionModuleResult result) {
  DCHECK(response);
  DCHECK(!session_id_.empty());
  DCHECK(thread_checker_.CalledOnValidThread());

  std::vector<uint8_t> sanitized_response;
  if (!SanitizeResponse(adapter_->GetKeySystem(), response, response_length,
                        &sanitized_response)) {
    result.completeWithError(
        blink::WebContentDecryptionModuleExceptionInvalidAccessError, 0,
        "Invalid response.");
    return;
  }

  adapter_->UpdateSession(
      session_id_, sanitized_response,
      std::unique_ptr<SimpleCdmPromise>(new CdmResultPromise<>(
          result, adapter_->GetKeySystemUMAPrefix() + kUpdateSessionUMAName)));
}

void WebContentDecryptionModuleSessionImpl::close(
    blink::WebContentDecryptionModuleResult result) {
  DCHECK(!session_id_.empty());
  DCHECK(thread_checker_.CalledOnValidThread());
  adapter_->CloseSession(
      session_id_,
      std::unique_ptr<SimpleCdmPromise>(new CdmResultPromise<>(
          result, adapter_->GetKeySystemUMAPrefix() + kCloseSessionUMAName)));
}

void WebContentDecryptionModuleSessionImpl::remove(
    blink::WebContentDecryptionModuleResult result) {
  DCHECK(!session_id_.empty());
  DCHECK(thread_checker_.CalledOnValidThread());
  adapter_->RemoveSession(
      session_id_,
      std::unique_ptr<SimpleCdmPromise>(new CdmResultPromise<>(
          result, adapter_->GetKeySystemUMAPrefix() + kRemoveSessionUMAName)));
}

void WebContentDecryptionModuleSessionImpl::OnSessionMessage(
    MediaKeys::MessageType message_type, const std::vector<uint8_t>& message) {
  DCHECK(client_) << "Client not set before message event";
  DCHECK(thread_checker_.CalledOnValidThread());
  client_->message(convertMessageType(message_type), message.data(),
                   message.size());
}

void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange(
    bool has_additional_usable_key, CdmKeysInfo keys_info) {
  DCHECK(thread_checker_.CalledOnValidThread());
  blink::WebVector<blink::WebEncryptedMediaKeyInformation> keys(
      keys_info.size());
  for (size_t i = 0; i < keys_info.size(); ++i) {
    auto* key_info = keys_info[i];
    keys[i].setId(blink::WebData(reinterpret_cast<char*>(&key_info->key_id[0]),
                                 key_info->key_id.size()));
    keys[i].setStatus(convertStatus(key_info->status));
    keys[i].setSystemCode(key_info->system_code);
  }

  // Now send the event to blink.
  client_->keysStatusesChange(keys, has_additional_usable_key);
}

void WebContentDecryptionModuleSessionImpl::OnSessionExpirationUpdate(
    const base::Time& new_expiry_time) {
  DCHECK(thread_checker_.CalledOnValidThread());
  client_->expirationChanged(new_expiry_time.ToJsTime());
}

void WebContentDecryptionModuleSessionImpl::OnSessionClosed() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (is_closed_) return;

  is_closed_ = true;
  client_->close();
}

void WebContentDecryptionModuleSessionImpl::OnSessionInitialized(
    const std::string& session_id, SessionInitStatus* status) {
  DCHECK(thread_checker_.CalledOnValidThread());
  // CDM will return NULL if the session to be loaded can't be found.
  if (session_id.empty()) {
    *status = SessionInitStatus::SESSION_NOT_FOUND;
    return;
  }

  DCHECK(session_id_.empty()) << "Session ID may not be changed once set.";
  session_id_ = session_id;
  *status =
      adapter_->RegisterSession(session_id_, weak_ptr_factory_.GetWeakPtr())
          ? SessionInitStatus::NEW_SESSION
          : SessionInitStatus::SESSION_ALREADY_EXISTS;
}

}  // namespace media
}  // namespace cobalt
