// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/dom/eme/media_key_session.h"

#include <type_traits>

#include "cobalt/dom/array_buffer.h"
#include "cobalt/dom/array_buffer_view.h"
#include "cobalt/dom/dom_exception.h"
#include "cobalt/dom/eme/media_key_message_event.h"
#include "cobalt/dom/eme/media_key_message_event_init.h"
#include "cobalt/dom/eme/media_keys.h"
#include "cobalt/script/script_value_factory.h"

namespace cobalt {
namespace dom {
namespace eme {

// See step 3.1 of
// https://www.w3.org/TR/encrypted-media/#dom-mediakeys-createsession.
MediaKeySession::MediaKeySession(
    const scoped_refptr<media::DrmSystem>& drm_system,
    script::ScriptValueFactory* script_value_factory,
    const ClosedCallback& closed_callback)
    : ALLOW_THIS_IN_INITIALIZER_LIST(event_queue_(this)),
      drm_system_(drm_system),
      drm_system_session_(drm_system->CreateSession(
#if SB_HAS(DRM_KEY_STATUSES)
          base::Bind(&MediaKeySession::OnSessionUpdateKeyStatuses,
                     base::AsWeakPtr(this))
#endif  // SB_HAS(DRM_KEY_STATUSES)
#if SB_HAS(DRM_SESSION_CLOSED)
          ,
          base::Bind(&MediaKeySession::OnSessionClosed,
                     base::AsWeakPtr(this))
#endif  // SB_HAS(DRM_SESSION_CLOSED)
              )),  // NOLINT(whitespace/parens)
      script_value_factory_(script_value_factory),
      uninitialized_(true),
      callable_(false),
      key_status_map_(new MediaKeyStatusMap),
      closed_callback_(closed_callback),
      ALLOW_THIS_IN_INITIALIZER_LIST(closed_promise_reference_(
          this, script_value_factory->CreateBasicPromise<void>())),
      initiated_by_generate_request_(false) {
}

// According to the step 3.1 of
// https://www.w3.org/TR/encrypted-media/#dom-mediakeys-createsession,
// session ID should be empty until the first request is generated successfully.
std::string MediaKeySession::session_id() const {
  return drm_system_session_->id().value_or("");
}

MediaKeySession::~MediaKeySession() {}

const MediaKeySession::VoidPromiseValue* MediaKeySession::closed() const {
  return &closed_promise_reference_.referenced_value();
}

const scoped_refptr<MediaKeyStatusMap>& MediaKeySession::key_statuses() const {
  return key_status_map_;
}

const EventTarget::EventListenerScriptValue*
MediaKeySession::onkeystatuseschange() const {
  return GetAttributeEventListener(base::Tokens::keystatuseschange());
}

void MediaKeySession::set_onkeystatuseschange(
    const EventListenerScriptValue& event_listener) {
  SetAttributeEventListener(base::Tokens::keystatuseschange(), event_listener);
}

const EventTarget::EventListenerScriptValue* MediaKeySession::onmessage()
    const {
  return GetAttributeEventListener(base::Tokens::message());
}

void MediaKeySession::set_onmessage(
    const EventListenerScriptValue& event_listener) {
  SetAttributeEventListener(base::Tokens::message(), event_listener);
}

// See
// https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-generaterequest.
script::Handle<script::Promise<void>> MediaKeySession::GenerateRequest(
    const std::string& init_data_type, const BufferSource& init_data) {
  script::Handle<script::Promise<void>> promise =
      script_value_factory_->CreateBasicPromise<void>();

  // 1. If this object is closed, return a promise rejected with
  //    an InvalidStateError.
  // 2. If this object's uninitialized value is false, return a promise rejected
  //    with an InvalidStateError.
  if (drm_system_session_->is_closed() || !uninitialized_) {
    promise->Reject(new DOMException(DOMException::kInvalidStateErr));
    return promise;
  }

  // 3. Let this object's uninitialized value be false.
  uninitialized_ = false;

  const uint8* init_data_buffer;
  int init_data_buffer_size;
  GetBufferAndSize(init_data, &init_data_buffer, &init_data_buffer_size);

  // 4. If initDataType is the empty string, return a promise rejected with
  //    a newly created TypeError.
  // 5. If initData is an empty array, return a promise rejected with a newly
  //    created TypeError.
  if (init_data_type.empty() || init_data_buffer_size == 0) {
    promise->Reject(script::kTypeError);
    return promise;
  }

  // 10.2. The user agent must thoroughly validate the initialization data
  //       before passing it to the CDM.
  //
  // Sanitation is the responsibility of Starboard implementers.

  // 10.9. Use the CDM.
  initiated_by_generate_request_ = true;
  drm_system_session_->GenerateUpdateRequest(
      init_data_type, init_data_buffer, init_data_buffer_size,
      base::Bind(&MediaKeySession::OnSessionUpdateRequestGenerated,
                 base::AsWeakPtr(this),
                 base::Owned(new VoidPromiseValue::Reference(this, promise))),
      base::Bind(&MediaKeySession::OnSessionUpdateRequestDidNotGenerate,
                 base::AsWeakPtr(this),
                 base::Owned(new VoidPromiseValue::Reference(this, promise))));

  // 11. Return promise.
  return promise;
}

// See https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-update.
script::Handle<script::Promise<void>> MediaKeySession::Update(
    const BufferSource& response) {
  script::Handle<script::Promise<void>> promise =
      script_value_factory_->CreateBasicPromise<void>();

  // 1. If this object is closed, return a promise rejected with
  //    an InvalidStateError.
  // 2. If this object's callable value is false, return a promise rejected
  //    with an InvalidStateError.
  if (drm_system_session_->is_closed() || !callable_) {
    promise->Reject(new DOMException(DOMException::kInvalidStateErr));
    return promise;
  }

  const uint8* response_buffer;
  int response_buffer_size;
  GetBufferAndSize(response, &response_buffer, &response_buffer_size);

  // 3. If response is an empty array, return a promise rejected with a newly
  //    created TypeError.
  if (response_buffer_size == 0) {
    promise->Reject(script::kTypeError);
    return promise;
  }

  // 6.1. Let sanitized response be a validated and/or sanitized version of
  //      response copy.
  //
  // Sanitation is the responsibility of Starboard implementers.

  // 6.7. Use the CDM.
  drm_system_session_->Update(
      response_buffer, response_buffer_size,
      base::Bind(&MediaKeySession::OnSessionUpdated, base::AsWeakPtr(this),
                 base::Owned(new VoidPromiseValue::Reference(this, promise))),
      base::Bind(&MediaKeySession::OnSessionDidNotUpdate, base::AsWeakPtr(this),
                 base::Owned(new VoidPromiseValue::Reference(this, promise))));

  // 7. Return promise.
  return promise;
}

// See https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-close.
script::Handle<script::Promise<void>> MediaKeySession::Close() {
  script::Handle<script::Promise<void>> promise =
      script_value_factory_->CreateBasicPromise<void>();

  // 2. If session is closed, return a resolved promise.
  if (drm_system_session_->is_closed()) {
    promise->Resolve();
    return promise;
  }

  // 3. If session's callable value is false, return a promise rejected with
  //    an InvalidStateError.
  if (!callable_) {
    promise->Reject(new DOMException(DOMException::kInvalidStateErr));
    return promise;
  }

  // 5.2. Use CDM to close the key session associated with session.
  drm_system_session_->Close();

  // Let |MediaKeys| know that the session should be removed from the list
  // of open sessions.
  closed_callback_.Run(this);

  // 5.3.1. Run the Session Closed algorithm on the session.
  OnSessionClosed();

  // 5.3.2. Resolve promise.
  promise->Resolve();
  return promise;
}

void MediaKeySession::TraceMembers(script::Tracer* tracer) {
  EventTarget::TraceMembers(tracer);

  tracer->Trace(event_queue_);
  tracer->Trace(key_status_map_);
}

// See
// https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-generaterequest.
void MediaKeySession::OnSessionUpdateRequestGenerated(
    VoidPromiseValue::Reference* promise_reference, scoped_array<uint8> message,
    int message_size) {
  MediaKeyMessageEventInit media_key_message_event_init;
  // 10.9.4. If a license request for the requested license type can be
  //         generated based on the sanitized init data:
  // 10.9.4.1. Let message be a license request for the requested license type
  //           generated based on the sanitized init data interpreted
  //           per initDataType.
  // Otherwise:
  // 10.9.4.1. Let message be the request that needs to be processed before
  //           a license request request for the requested license type can be
  //           generated based on the sanitized init data.
  media_key_message_event_init.set_message(
      new ArrayBuffer(NULL, message.Pass(), message_size));
  // 10.9.4.2. Let message type reflect the type of message, either
  //           "license-request" or "individualization-request".
  //
  // TODO: Introduce message type parameter to |SbDrmSessionUpdateRequestFunc|
  //       and stop pretending that all messages are license requests.
  media_key_message_event_init.set_message_type(
      kMediaKeyMessageTypeLicenseRequest);

  // 10.3. Let this object's callable value be true.
  callable_ = true;

  // 10.4. Run the Queue a "message" Event algorithm on the session.
  //
  // TODO: Implement Event.isTrusted as per
  //       https://www.w3.org/TR/dom/#dom-event-istrusted and set it to true.
  event_queue_.Enqueue(
      new MediaKeyMessageEvent("message", media_key_message_event_init));

  // 10.5. Resolve promise.
  //
  // If the request was generated spontaneously by the underlying DRM system,
  // we shouldn't resolve the promise returned by |GenerateRequest|. The promise
  // was resolved in the first invocation of this method and now is simply
  // hanging around.
  if (initiated_by_generate_request_) {
    initiated_by_generate_request_ = false;
    promise_reference->value().Resolve();
  }
}

// See
// https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-generaterequest.
void MediaKeySession::OnSessionUpdateRequestDidNotGenerate(
    VoidPromiseValue::Reference* promise_reference) {
  // 10.10.1. If any of the preceding steps failed, reject promise with a new
  //          DOMException whose name is the appropriate error name.
  //
  // TODO: Introduce Starboard API that allows CDM to propagate error codes.
  promise_reference->value().Reject(new DOMException(DOMException::kNone));
}

// See https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-update.
void MediaKeySession::OnSessionUpdated(
    VoidPromiseValue::Reference* promise_reference) {
  // 8.1.1. If the set of keys known to the CDM for this object changed or
  //        the status of any key(s) changed, run the Update Key Statuses
  //        algorithm on the session.
  //
  // TODO: Implement key statuses.

  // 8.1.2. If the expiration time for the session changed, run the Update
  //        Expiration algorithm on the session.
  //
  // TODO: Implement expiration.

  // 8.2. Resolve promise.
  promise_reference->value().Resolve();
}

// See https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-update.
void MediaKeySession::OnSessionDidNotUpdate(
    VoidPromiseValue::Reference* promise_reference) {
  // 8.1.3. If any of the preceding steps failed, reject promise with a new
  //        DOMException whose name is the appropriate error name.
  //
  // TODO: Introduce Starboard API that allows CDM to propagate error codes.
  promise_reference->value().Reject(new DOMException(DOMException::kNone));
}

// See https://www.w3.org/TR/encrypted-media/#update-key-statuses.
void MediaKeySession::OnSessionUpdateKeyStatuses(
    const std::vector<std::string>& key_ids,
    const std::vector<SbDrmKeyStatus>& key_statuses) {
#define CHECK_KEY_STATUS_ENUM(starboard_value, dom_value)                  \
  static_assert(static_cast<MediaKeyStatus>(starboard_value) == dom_value, \
                "key status enum value mismatch");

  CHECK_KEY_STATUS_ENUM(kSbDrmKeyStatusUsable, kMediaKeyStatusUsable);
  CHECK_KEY_STATUS_ENUM(kSbDrmKeyStatusExpired, kMediaKeyStatusExpired);
  CHECK_KEY_STATUS_ENUM(kSbDrmKeyStatusReleased, kMediaKeyStatusReleased);
  CHECK_KEY_STATUS_ENUM(kSbDrmKeyStatusRestricted,
                        kMediaKeyStatusOutputRestricted);
  CHECK_KEY_STATUS_ENUM(kSbDrmKeyStatusDownscaled,
                        kMediaKeyStatusOutputDownscaled);
  CHECK_KEY_STATUS_ENUM(kSbDrmKeyStatusPending, kMediaKeyStatusStatusPending);
  CHECK_KEY_STATUS_ENUM(kSbDrmKeyStatusError, kMediaKeyStatusInternalError);

  DCHECK_EQ(key_ids.size(), key_statuses.size());

  // 1. Let the session be the associated MediaKeySession object.
  // 2. Let the input statuses be the sequence of pairs key ID and associated
  //    MediaKeyStatus pairs.
  // 3. Let the statuses be session's keyStatuses attribute.
  // 4. Run the following steps to replace the contents of statuses:
  // 4.1. Empty statuses.
  key_status_map_->Clear();

  // 4.2. For each pair in input statuses.
  for (size_t i = 0; i < key_ids.size(); ++i) {
    // 4.2.1. Let pair be the pair.
    // 4.2.2. Insert an entry for pair's key ID into statuses with the value of
    //        pair's MediaKeyStatus value.
    DCHECK_GE(key_statuses[i], kSbDrmKeyStatusUsable);
    DCHECK_LE(key_statuses[i], kSbDrmKeyStatusError);

    if (key_statuses[i] < kSbDrmKeyStatusUsable ||
        key_statuses[i] > kSbDrmKeyStatusError) {
      key_status_map_->Add(key_ids[i], kMediaKeyStatusInternalError);
    } else {
      key_status_map_->Add(key_ids[i],
                           static_cast<MediaKeyStatus>(key_statuses[i]));
    }
  }

  // 5. Queue a task to fire a simple event named keystatuseschange at the
  //    session.
  LOG(INFO) << "Fired 'keystatuseschange' event on MediaKeySession with "
            << key_status_map_->size() << " keys.";
  event_queue_.Enqueue(new Event(base::Tokens::keystatuseschange()));

  // 6. Queue a task to run the Attempt to Resume Playback If Necessary
  //    algorithm on each of the media element(s) whose mediaKeys attribute is
  //    the MediaKeys object that created the session.
}

// See https://www.w3.org/TR/encrypted-media/#session-closed.
void MediaKeySession::OnSessionClosed() {
  // 2. Run the Update Key Statuses algorithm on the session, providing an empty
  //    sequence.
  //
  // TODO: Implement key statuses.

  // 3. Run the Update Expiration algorithm on the session, providing NaN.
  //
  // TODO: Implement expiration.

  // 4. Let promise be the closed attribute of the session.
  // 5. Resolve promise.
  closed_promise_reference_.value().Resolve();
}

}  // namespace eme
}  // namespace dom
}  // namespace cobalt
