// 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_MEDIA_BASE_DRM_SYSTEM_H_
#define COBALT_MEDIA_BASE_DRM_SYSTEM_H_

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

#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "starboard/drm.h"

namespace cobalt {
namespace media {

// A C++ wrapper around |SbDrmSystem|.
//
// Ensures that callbacks are always asynchronous and performed
// from the same thread where |DrmSystem| was instantiated.
class DrmSystem : public base::RefCounted<DrmSystem> {
 public:
  typedef base::Callback<void(SbDrmSessionRequestType type,
                              std::unique_ptr<uint8[]> message,
                              int message_size)>
      SessionUpdateRequestGeneratedCallback;
  typedef base::Callback<void(SbDrmStatus status,
                              const std::string& error_message)>
      SessionUpdateRequestDidNotGenerateCallback;
  typedef base::Callback<void()> SessionUpdatedCallback;
  typedef base::Callback<void(SbDrmStatus status,
                              const std::string& error_message)>
      SessionDidNotUpdateCallback;
#if SB_HAS(DRM_KEY_STATUSES)
  typedef base::Callback<void(const std::vector<std::string>& key_ids,
                              const std::vector<SbDrmKeyStatus>& key_statuses)>
      SessionUpdateKeyStatusesCallback;
#endif  // SB_HAS(DRM_KEY_STATUSES)
#if SB_HAS(DRM_SESSION_CLOSED)
  typedef base::Callback<void()> SessionClosedCallback;
#endif  // SB_HAS(DRM_SESSION_CLOSED)
  typedef base::Callback<void(SbDrmStatus status,
                              const std::string& error_message)>
      ServerCertificateUpdatedCallback;

  // Flyweight that provides RAII semantics for sessions.
  // Most of logic is implemented by |DrmSystem| and thus sessions must be
  // destroyed before |DrmSystem|.
  class Session {
   public:
    ~Session();

    const base::Optional<std::string>& id() const { return id_; }

    // Wraps |SbDrmGenerateSessionUpdateRequest|.
    //
    // |session_update_request_generated_callback| is called upon a successful
    //     request generation. IMPORTANT: It may be called multiple times after
    //     a single call to |CreateSessionAndGenerateUpdateRequest|, for example
    //     when the underlying DRM system needs to update a license.
    //
    // |session_update_request_did_not_generate_callback| is called upon a
    //     failure during request generation. Unlike its successful counterpart,
    //     never called spontaneously.
    void GenerateUpdateRequest(
        const std::string& type, const uint8* init_data, int init_data_length,
        const SessionUpdateRequestGeneratedCallback&
            session_update_request_generated_callback,
        const SessionUpdateRequestDidNotGenerateCallback&
            session_update_request_did_not_generate_callback);

    // Wraps |SbDrmUpdateSession|.
    //
    // |session_updated_callback| is called upon a successful session update.
    // |session_did_not_update_callback| is called upon a failure during session
    //     update.
    void Update(
        const uint8* key, int key_length,
        const SessionUpdatedCallback& session_updated_callback,
        const SessionDidNotUpdateCallback& session_did_not_update_callback);

    // Wraps |SbDrmCloseSession|.
    void Close();
    bool is_closed() const { return closed_; }

   private:
    // Private API for |DrmSystem|.
    Session(DrmSystem* drm_system
#if SB_HAS(DRM_KEY_STATUSES)
            ,
            SessionUpdateKeyStatusesCallback update_key_statuses_callback
#endif  // SB_HAS(DRM_KEY_STATUSES)
#if SB_HAS(DRM_SESSION_CLOSED)
            ,
            SessionClosedCallback session_closed_callback
#endif          // SB_HAS(SESSION_CLOSED)
            );  // NOLINT(whitespace/parens)
    void set_id(const std::string& id) { id_ = id; }
    const SessionUpdateRequestGeneratedCallback&
    update_request_generated_callback() const {
      return update_request_generated_callback_;
    }
#if SB_HAS(DRM_KEY_STATUSES)
    const SessionUpdateKeyStatusesCallback& update_key_statuses_callback()
        const {
      return update_key_statuses_callback_;
    }
#endif  // SB_HAS(DRM_KEY_STATUSES)
#if SB_HAS(DRM_SESSION_CLOSED)
    const SessionClosedCallback& session_closed_callback() const {
      return session_closed_callback_;
    }
#endif  // SB_HAS(DRM_SESSION_CLOSED)

    DrmSystem* const drm_system_;
#if SB_HAS(DRM_KEY_STATUSES)
    SessionUpdateKeyStatusesCallback update_key_statuses_callback_;
#endif  // SB_HAS(DRM_KEY_STATUSES)
#if SB_HAS(DRM_SESSION_CLOSED)
    SessionClosedCallback session_closed_callback_;
#endif  // SB_HAS(DRM_SESSION_CLOSED)
    bool closed_;
    base::Optional<std::string> id_;
    // Supports spontaneous invocations of |SbDrmSessionUpdateRequestFunc|.
    SessionUpdateRequestGeneratedCallback update_request_generated_callback_;

    friend class DrmSystem;

    DISALLOW_COPY_AND_ASSIGN(Session);
  };

  explicit DrmSystem(const char* key_system);
  ~DrmSystem();

  SbDrmSystem wrapped_drm_system() { return wrapped_drm_system_; }

  std::unique_ptr<Session> CreateSession(
#if SB_HAS(DRM_KEY_STATUSES)
      SessionUpdateKeyStatusesCallback session_update_key_statuses_callback
#endif  // SB_HAS(DRM_KEY_STATUSES)
#if SB_HAS(DRM_SESSION_CLOSED)
      ,
      SessionClosedCallback session_closed_callback
#endif    // SB_HAS(DRM_SESSION_CLOSED)
      );  // NOLINT(whitespace/parens)

  bool IsServerCertificateUpdatable();
  void UpdateServerCertificate(
      const uint8_t* certificate, int certificate_size,
      ServerCertificateUpdatedCallback server_certificate_updated_callback);

 private:
  // Stores context of |GenerateSessionUpdateRequest|.
  struct SessionUpdateRequest {
    Session* session;
    SessionUpdateRequestGeneratedCallback generated_callback;
    SessionUpdateRequestDidNotGenerateCallback did_not_generate_callback;
  };
  typedef base::hash_map<int, SessionUpdateRequest>
      TicketToSessionUpdateRequestMap;

  typedef base::hash_map<std::string, Session*> IdToSessionMap;

  typedef base::hash_map<int, ServerCertificateUpdatedCallback>
      TicketToServerCertificateUpdatedMap;

  // Stores context of |Session::Update|.
  struct SessionUpdate {
    SessionUpdatedCallback updated_callback;
    SessionDidNotUpdateCallback did_not_update_callback;
  };
  typedef base::hash_map<int, SessionUpdate> TicketToSessionUpdateMap;

  // Defined to work around the limitation on number of parameters of
  // base::Bind().
  struct SessionTicketAndOptionalId {
    int ticket;
    base::Optional<std::string> id;
  };

  // Private API for |Session|.
  void GenerateSessionUpdateRequest(
      Session* session, const std::string& type, const uint8_t* init_data,
      int init_data_length,
      const SessionUpdateRequestGeneratedCallback&
          session_update_request_generated_callback,
      const SessionUpdateRequestDidNotGenerateCallback&
          session_update_request_did_not_generate_callback);
  void UpdateSession(
      const std::string& session_id, const uint8_t* key, int key_length,
      const SessionUpdatedCallback& session_updated_callback,
      const SessionDidNotUpdateCallback& session_did_not_update_callback);
  void CloseSession(const std::string& session_id);

  // Called on the constructor thread, parameters are copied and owned by these
  // methods.
  void OnSessionUpdateRequestGenerated(
      SessionTicketAndOptionalId ticket_and_optional_id, SbDrmStatus status,
      SbDrmSessionRequestType type, const std::string& error_message,
      std::unique_ptr<uint8[]> message, int message_size);
  void OnSessionUpdated(int ticket, SbDrmStatus status,
                        const std::string& error_message);
#if SB_HAS(DRM_KEY_STATUSES)
  void OnSessionKeyStatusChanged(
      const std::string& session_id, const std::vector<std::string>& key_ids,
      const std::vector<SbDrmKeyStatus>& key_statuses);
#endif  // SB_HAS(DRM_KEY_STATUSES)
#if SB_API_VERSION >= 10
  void OnServerCertificateUpdated(int ticket, SbDrmStatus status,
                                  const std::string& error_message);
#endif  // SB_API_VERSION >= 10
#if SB_HAS(DRM_SESSION_CLOSED)
  void OnSessionClosed(const std::string& session_id);
#endif  // SB_HAS(DRM_SESSION_CLOSED)
// Called on any thread, parameters need to be copied immediately.

#if SB_API_VERSION >= 10
  static void OnSessionUpdateRequestGeneratedFunc(
      SbDrmSystem wrapped_drm_system, void* context, int ticket,
      SbDrmStatus status, SbDrmSessionRequestType type,
      const char* error_message, const void* session_id, int session_id_size,
      const void* content, int content_size, const char* url);
  static void OnSessionUpdatedFunc(SbDrmSystem wrapped_drm_system,
                                   void* context, int ticket,
                                   SbDrmStatus status,
                                   const char* error_message,
                                   const void* session_id,
                                   int session_id_length);
#else   // SB_API_VERSION >= 10
  static void OnSessionUpdateRequestGeneratedFunc(
      SbDrmSystem wrapped_drm_system, void* context, int ticket,
      const void* session_id, int session_id_size, const void* content,
      int content_size, const char* url);
  static void OnSessionUpdatedFunc(SbDrmSystem wrapped_drm_system,
                                   void* context, int ticket,
                                   const void* session_id,
                                   int session_id_length, bool succeeded);
#endif  // SB_API_VERSION >= 10

#if SB_HAS(DRM_KEY_STATUSES)
  static void OnSessionKeyStatusesChangedFunc(
      SbDrmSystem wrapped_drm_system, void* context, const void* session_id,
      int session_id_size, int number_of_keys, const SbDrmKeyId* key_ids,
      const SbDrmKeyStatus* key_statuses);
#endif  // SB_HAS(DRM_KEY_STATUSES)

#if SB_HAS(DRM_SESSION_CLOSED)
  static void OnSessionClosedFunc(SbDrmSystem wrapped_drm_system, void* context,
                                  const void* session_id, int session_id_size);
#endif  // SB_HAS(DRM_SESSION_CLOSED)

#if SB_API_VERSION >= 10
  static void OnServerCertificateUpdatedFunc(SbDrmSystem wrapped_drm_system,
                                             void* context, int ticket,
                                             SbDrmStatus status,
                                             const char* error_message);
#endif  // SB_API_VERSION >= 10

  const SbDrmSystem wrapped_drm_system_;
  scoped_refptr<base::SingleThreadTaskRunner> const message_loop_;

  // Factory should only be used to create the initial weak pointer. All
  // subsequent weak pointers are created by copying the initial one. This is
  // required to keep weak pointers bound to the constructor thread.
  base::WeakPtrFactory<DrmSystem> weak_ptr_factory_;
  base::WeakPtr<DrmSystem> weak_this_;

  int next_ticket_ = 0;
  // Supports concurrent calls to |GenerateSessionUpdateRequest|.
  TicketToSessionUpdateRequestMap ticket_to_session_update_request_map_;

  // Supports spontaneous invocations of |SbDrmSessionUpdateRequestFunc|.
  IdToSessionMap id_to_session_map_;

  TicketToServerCertificateUpdatedMap ticket_to_server_certificate_updated_map_;

  // Supports concurrent calls to |Session::Update|.
  TicketToSessionUpdateMap ticket_to_session_update_map_;

  DISALLOW_COPY_AND_ASSIGN(DrmSystem);
};

}  // namespace media
}  // namespace cobalt

#endif  // COBALT_MEDIA_BASE_DRM_SYSTEM_H_
