// Copyright 2020 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 "media/cdm/win/media_foundation_cdm_session.h"

#include <memory>

#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_co_mem.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_key_information.h"
#include "media/base/win/mf_helpers.h"

namespace media {

namespace {

using Microsoft::WRL::ClassicCom;
using Microsoft::WRL::ComPtr;
using Microsoft::WRL::MakeAndInitialize;
using Microsoft::WRL::RuntimeClass;
using Microsoft::WRL::RuntimeClassFlags;

MF_MEDIAKEYSESSION_TYPE ToMFSessionType(CdmSessionType session_type) {
  switch (session_type) {
    case CdmSessionType::kTemporary:
      return MF_MEDIAKEYSESSION_TYPE_TEMPORARY;
    case CdmSessionType::kPersistentLicense:
      return MF_MEDIAKEYSESSION_TYPE_PERSISTENT_LICENSE;
  }
}

// The strings are defined in https://www.w3.org/TR/eme-initdata-registry/
LPCWSTR InitDataTypeToString(EmeInitDataType init_data_type) {
  switch (init_data_type) {
    case EmeInitDataType::UNKNOWN:
      return L"unknown";
    case EmeInitDataType::WEBM:
      return L"webm";
    case EmeInitDataType::CENC:
      return L"cenc";
    case EmeInitDataType::KEYIDS:
      return L"keyids";
  }
}

CdmMessageType ToCdmMessageType(MF_MEDIAKEYSESSION_MESSAGETYPE message_type) {
  switch (message_type) {
    case MF_MEDIAKEYSESSION_MESSAGETYPE_LICENSE_REQUEST:
      return CdmMessageType::LICENSE_REQUEST;
    case MF_MEDIAKEYSESSION_MESSAGETYPE_LICENSE_RENEWAL:
      return CdmMessageType::LICENSE_RENEWAL;
    case MF_MEDIAKEYSESSION_MESSAGETYPE_LICENSE_RELEASE:
      return CdmMessageType::LICENSE_RELEASE;
    case MF_MEDIAKEYSESSION_MESSAGETYPE_INDIVIDUALIZATION_REQUEST:
      return CdmMessageType::INDIVIDUALIZATION_REQUEST;
  }
}

CdmKeyInformation::KeyStatus ToCdmKeyStatus(MF_MEDIAKEY_STATUS status) {
  switch (status) {
    case MF_MEDIAKEY_STATUS_USABLE:
      return CdmKeyInformation::KeyStatus::USABLE;
    case MF_MEDIAKEY_STATUS_EXPIRED:
      return CdmKeyInformation::KeyStatus::EXPIRED;
    case MF_MEDIAKEY_STATUS_OUTPUT_DOWNSCALED:
      return CdmKeyInformation::KeyStatus::OUTPUT_DOWNSCALED;
    // This is for legacy use and should not happen in normal cases. Map it to
    // internal error in case it happens.
    case MF_MEDIAKEY_STATUS_OUTPUT_NOT_ALLOWED:
      return CdmKeyInformation::KeyStatus::INTERNAL_ERROR;
    case MF_MEDIAKEY_STATUS_STATUS_PENDING:
      return CdmKeyInformation::KeyStatus::KEY_STATUS_PENDING;
    case MF_MEDIAKEY_STATUS_INTERNAL_ERROR:
      return CdmKeyInformation::KeyStatus::INTERNAL_ERROR;
    case MF_MEDIAKEY_STATUS_RELEASED:
      return CdmKeyInformation::KeyStatus::RELEASED;
    case MF_MEDIAKEY_STATUS_OUTPUT_RESTRICTED:
      return CdmKeyInformation::KeyStatus::OUTPUT_RESTRICTED;
  }
}

CdmKeysInfo ToCdmKeysInfo(const MFMediaKeyStatus* key_statuses, int count) {
  CdmKeysInfo keys_info;
  keys_info.reserve(count);
  for (int i = 0; i < count; ++i) {
    const auto& key_status = key_statuses[i];
    keys_info.push_back(std::make_unique<CdmKeyInformation>(
        key_status.pbKeyId, key_status.cbKeyId,
        ToCdmKeyStatus(key_status.eMediaKeyStatus), /*system_code=*/0));
  }
  return keys_info;
}

class SessionCallbacks final
    : public RuntimeClass<RuntimeClassFlags<ClassicCom>,
                          IMFContentDecryptionModuleSessionCallbacks> {
 public:
  SessionCallbacks() { DVLOG_FUNC(1); }
  SessionCallbacks(const SessionCallbacks&) = delete;
  SessionCallbacks& operator=(const SessionCallbacks&) = delete;
  ~SessionCallbacks() override { DVLOG_FUNC(1); }

  using MessageCB =
      base::RepeatingCallback<void(CdmMessageType message_type,
                                   const std::vector<uint8_t>& message)>;
  using KeysChangeCB = base::RepeatingClosure;

  HRESULT RuntimeClassInitialize(MessageCB message_cb,
                                 KeysChangeCB keys_change_cb) {
    message_cb_ = std::move(message_cb);
    keys_change_cb_ = std::move(keys_change_cb);
    return S_OK;
  }

  // IMFContentDecryptionModuleSessionCallbacks implementation

  STDMETHODIMP KeyMessage(MF_MEDIAKEYSESSION_MESSAGETYPE message_type,
                          const BYTE* message,
                          DWORD message_size,
                          LPCWSTR destination_url) final {
    DVLOG_FUNC(2) << ": message size=" << message_size;
    message_cb_.Run(ToCdmMessageType(message_type),
                    std::vector<uint8_t>(message, message + message_size));
    return S_OK;
  }

  STDMETHODIMP KeyStatusChanged() final {
    DVLOG_FUNC(2);
    keys_change_cb_.Run();
    return S_OK;
  }

 private:
  MessageCB message_cb_;
  KeysChangeCB keys_change_cb_;
};

}  // namespace

MediaFoundationCdmSession::MediaFoundationCdmSession(
    const SessionMessageCB& session_message_cb,
    const SessionKeysChangeCB& session_keys_change_cb,
    const SessionExpirationUpdateCB& session_expiration_update_cb)
    : session_message_cb_(session_message_cb),
      session_keys_change_cb_(session_keys_change_cb),
      session_expiration_update_cb_(session_expiration_update_cb) {
  DVLOG_FUNC(1);
}

MediaFoundationCdmSession::~MediaFoundationCdmSession() {
  DVLOG_FUNC(1);
}

HRESULT MediaFoundationCdmSession::Initialize(
    IMFContentDecryptionModule* mf_cdm,
    CdmSessionType session_type) {
  DVLOG_FUNC(1);

  ComPtr<SessionCallbacks> session_callbacks;
  auto weak_this = weak_factory_.GetWeakPtr();

  // Use BindToCurrentLoop() because the callbacks can be fired on different
  // threads by |mf_cdm_session_|.
  RETURN_IF_FAILED(MakeAndInitialize<SessionCallbacks>(
      &session_callbacks,
      BindToCurrentLoop(base::BindRepeating(
          &MediaFoundationCdmSession::OnSessionMessage, weak_this)),
      BindToCurrentLoop(base::BindRepeating(
          &MediaFoundationCdmSession::OnSessionKeysChange, weak_this))));

  // |mf_cdm_session_| holds a ref count to |session_callbacks|.
  RETURN_IF_FAILED(mf_cdm->CreateSession(ToMFSessionType(session_type),
                                         session_callbacks.Get(),
                                         &mf_cdm_session_));

  return S_OK;
}

HRESULT MediaFoundationCdmSession::GenerateRequest(
    EmeInitDataType init_data_type,
    const std::vector<uint8_t>& init_data,
    SessionIdCB session_id_cb) {
  DVLOG_FUNC(1);
  DCHECK(session_id_.empty() && !session_id_cb_);

  session_id_cb_ = std::move(session_id_cb);
  RETURN_IF_FAILED(mf_cdm_session_->GenerateRequest(
      InitDataTypeToString(init_data_type), init_data.data(),
      base::checked_cast<DWORD>(init_data.size())));
  return S_OK;
}

HRESULT MediaFoundationCdmSession::Load(const std::string& session_id) {
  DVLOG_FUNC(1);
  return E_NOTIMPL;
}

HRESULT
MediaFoundationCdmSession::Update(const std::vector<uint8_t>& response) {
  DVLOG_FUNC(1);
  RETURN_IF_FAILED(
      mf_cdm_session_->Update(reinterpret_cast<const BYTE*>(response.data()),
                              base::checked_cast<DWORD>(response.size())));
  RETURN_IF_FAILED(UpdateExpirationIfNeeded());
  return S_OK;
}

HRESULT MediaFoundationCdmSession::Close() {
  DVLOG_FUNC(1);
  RETURN_IF_FAILED(mf_cdm_session_->Close());
  return S_OK;
}

HRESULT MediaFoundationCdmSession::Remove() {
  DVLOG_FUNC(1);
  RETURN_IF_FAILED(mf_cdm_session_->Remove());
  RETURN_IF_FAILED(UpdateExpirationIfNeeded());
  return S_OK;
}

void MediaFoundationCdmSession::OnSessionMessage(
    CdmMessageType message_type,
    const std::vector<uint8_t>& message) {
  DVLOG_FUNC(2);

  if (session_id_.empty() && !session_id_cb_) {
    DLOG(ERROR) << "Unexpected session message";
    return;
  }

  // If |session_id_| has not been set, set it now.
  if (session_id_.empty() && !SetSessionId())
    return;

  DCHECK(!session_id_.empty());
  session_message_cb_.Run(session_id_, message_type, message);
}

void MediaFoundationCdmSession::OnSessionKeysChange() {
  DVLOG_FUNC(2);

  if (session_id_.empty()) {
    DLOG(ERROR) << "Unexpected session keys change ignored";
    return;
  }

  base::win::ScopedCoMem<MFMediaKeyStatus> key_statuses;

  UINT count = 0;
  if (FAILED(mf_cdm_session_->GetKeyStatuses(&key_statuses, &count))) {
    DLOG(ERROR) << __func__ << ": Failed to get key statuses";
    return;
  }

  // TODO(xhwang): Investigate whether we need to set |has_new_usable_key|.
  session_keys_change_cb_.Run(session_id_, /*has_new_usable_key=*/true,
                              ToCdmKeysInfo(key_statuses.get(), count));

  // ScopedCoMem<MFMediaKeyStatus> only releases memory for |key_statuses|. We
  // need to manually release memory for |pbKeyId| here.
  for (UINT i = 0; i < count; ++i) {
    const auto& key_status = key_statuses[i];
    if (key_status.pbKeyId)
      CoTaskMemFree(key_status.pbKeyId);
  }
}

bool MediaFoundationCdmSession::SetSessionId() {
  DCHECK(session_id_.empty() && session_id_cb_);

  base::win::ScopedCoMem<wchar_t> session_id;
  HRESULT hr = mf_cdm_session_->GetSessionId(&session_id);
  if (FAILED(hr) || !session_id) {
    bool success = std::move(session_id_cb_).Run("");
    DCHECK(!success) << "Empty session ID should not be accepted";
    return false;
  }

  auto session_id_str = base::WideToUTF8(session_id.get());
  if (session_id_str.empty()) {
    bool success = std::move(session_id_cb_).Run("");
    DCHECK(!success) << "Empty session ID should not be accepted";
    return false;
  }

  bool success = std::move(session_id_cb_).Run(session_id_str);
  if (!success) {
    DLOG(ERROR) << "Session ID " << session_id_str << " rejected";
    return false;
  }

  DVLOG_FUNC(1) << "session_id_=" << session_id_str;
  session_id_ = session_id_str;
  return true;
}

HRESULT MediaFoundationCdmSession::UpdateExpirationIfNeeded() {
  DCHECK(!session_id_.empty());

  // Media Foundation CDM follows the EME spec where Time generally represents
  // an instant in time with millisecond accuracy.
  double new_expiration_ms = 0.0;
  RETURN_IF_FAILED(mf_cdm_session_->GetExpiration(&new_expiration_ms));
  auto new_expiration = base::Time::FromJsTime(new_expiration_ms);

  if (new_expiration == expiration_)
    return S_OK;

  DVLOG(2) << "New session expiration: " << new_expiration;
  expiration_ = new_expiration;
  session_expiration_update_cb_.Run(session_id_, expiration_);
  return S_OK;
}

}  // namespace media
