// Copyright 2017 The Cobalt Authors. 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.

#ifndef COBALT_DOM_EME_MEDIA_KEY_SESSION_H_
#define COBALT_DOM_EME_MEDIA_KEY_SESSION_H_

#include <memory>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "cobalt/dom/eme/media_key_status.h"
#include "cobalt/dom/eme/media_key_status_map.h"
#include "cobalt/dom/event_queue.h"
#include "cobalt/media/base/drm_system.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/promise.h"
#include "cobalt/script/script_value_factory.h"
#include "cobalt/web/buffer_source.h"
#include "cobalt/web/event_target.h"
#include "starboard/drm.h"

namespace cobalt {
namespace dom {
namespace eme {

// A session provides a context for message exchange with the CDM as a result
// of which keys are made available to the CDM.
//   https://www.w3.org/TR/encrypted-media/#key-session
//
// Also see https://www.w3.org/TR/encrypted-media/#mediakeysession-interface.
class MediaKeySession : public web::EventTarget {
 public:
  typedef script::ScriptValue<script::Promise<void>> VoidPromiseValue;
  typedef base::Callback<void(MediaKeySession* session)> ClosedCallback;

  // Custom, not in any spec.
  MediaKeySession(script::EnvironmentSettings* settings,
                  const scoped_refptr<media::DrmSystem>& drm_system,
                  script::ScriptValueFactory* script_value_factory,
                  const ClosedCallback& closed_callback);

  // Web IDL: MediaKeySession.
  std::string session_id() const;
  const VoidPromiseValue* closed() const;
  const scoped_refptr<MediaKeyStatusMap>& key_statuses() const;
  const EventListenerScriptValue* onkeystatuseschange() const;
  void set_onkeystatuseschange(const EventListenerScriptValue& event_listener);
  const EventListenerScriptValue* onmessage() const;
  void set_onmessage(const EventListenerScriptValue& event_listener);
  script::Handle<script::Promise<void>> GenerateRequest(
      script::EnvironmentSettings* settings, const std::string& init_data_type,
      const web::BufferSource& init_data);
  script::Handle<script::Promise<void>> Update(
      const web::BufferSource& response);
  script::Handle<script::Promise<void>> Close();

  DEFINE_WRAPPABLE_TYPE(MediaKeySession);
  void TraceMembers(script::Tracer* tracer) override;

 private:
  ~MediaKeySession() override;

  void OnSessionUpdateRequestGenerated(
      script::EnvironmentSettings* settings,
      VoidPromiseValue::Reference* promise_reference,
      SbDrmSessionRequestType type, std::unique_ptr<uint8[]> message,
      int message_size);
  void OnSessionUpdateRequestDidNotGenerate(
      VoidPromiseValue::Reference* promise_reference, SbDrmStatus status,
      const std::string& error_message);
  void OnSessionUpdated(VoidPromiseValue::Reference* promise_reference);
  void OnSessionDidNotUpdate(VoidPromiseValue::Reference* promise_reference,
                             SbDrmStatus status,
                             const std::string& error_message);
  void OnSessionUpdateKeyStatuses(
      const std::vector<std::string>& key_ids,
      const std::vector<SbDrmKeyStatus>& key_statuses);
  void OnSessionClosed();

  EventQueue event_queue_;

  // Although it doesn't make much sense, it's possible to call session methods
  // when |MediaKeys| are destroyed. This behavior is underspecified but is
  // consistent with Chromium. For this reason we need to hold to |drm_system_|
  // from each session.
  const scoped_refptr<media::DrmSystem> drm_system_;
  std::unique_ptr<media::DrmSystem::Session> drm_system_session_;
  script::ScriptValueFactory* const script_value_factory_;
  bool uninitialized_;
  bool callable_;
  scoped_refptr<MediaKeyStatusMap> key_status_map_;

  const ClosedCallback closed_callback_;
  const VoidPromiseValue::Reference closed_promise_reference_;

  bool initiated_by_generate_request_;

  DISALLOW_COPY_AND_ASSIGN(MediaKeySession);
};

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

#endif  // COBALT_DOM_EME_MEDIA_KEY_SESSION_H_
