// Copyright 2016 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.

#ifndef COBALT_MEDIA_BASE_STARBOARD_PLAYER_H_
#define COBALT_MEDIA_BASE_STARBOARD_PLAYER_H_

#include <map>
#include <utility>

#include "base/memory/ref_counted.h"
#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "base/time.h"
#include "cobalt/media/base/audio_decoder_config.h"
#include "cobalt/media/base/decoder_buffer.h"
#include "cobalt/media/base/decoder_buffer_cache.h"
#include "cobalt/media/base/demuxer_stream.h"
#include "cobalt/media/base/sbplayer_set_bounds_helper.h"
#include "cobalt/media/base/video_decoder_config.h"
#include "starboard/media.h"
#include "starboard/player.h"

namespace cobalt {
namespace media {

// TODO: Add switch to disable caching
class StarboardPlayer {
 public:
  class Host {
   public:
    virtual void OnNeedData(DemuxerStream::Type type) = 0;
    virtual void OnPlayerStatus(SbPlayerState state) = 0;

   protected:
    ~Host() {}
  };

  StarboardPlayer(const scoped_refptr<base::MessageLoopProxy>& message_loop,
                  const AudioDecoderConfig& audio_config,
                  const VideoDecoderConfig& video_config, SbWindow window,
                  SbDrmSystem drm_system, Host* host,
                  SbPlayerSetBoundsHelper* set_bounds_helper,
                  bool prefer_decode_to_texture);
  ~StarboardPlayer();

  bool IsValid() const { return SbPlayerIsValid(player_); }

  void UpdateVideoResolution(int frame_width, int frame_height);

  void WriteBuffer(DemuxerStream::Type type,
                   const scoped_refptr<DecoderBuffer>& buffer);
  void SetBounds(const gfx::Rect& rect);

  void PrepareForSeek();
  void Seek(base::TimeDelta time);

  void SetVolume(float volume);
  void SetPlaybackRate(double playback_rate);
  void GetInfo(uint32* video_frames_decoded, uint32* video_frames_dropped,
               base::TimeDelta* media_time);

  void Suspend();
  void Resume();

#if SB_API_VERSION >= 4
  SbDecodeTarget GetCurrentSbDecodeTarget();
  SbPlayerOutputMode GetSbPlayerOutputMode();
#endif  // SB_API_VERSION >= 4

 private:
  enum State {
    kPlaying,
    kSuspended,
    kResuming,
  };

  // This class ensures that the callbacks posted to |message_loop_| are ignored
  // automatically once StarboardPlayer is destroyed.
  class CallbackHelper : public base::RefCountedThreadSafe<CallbackHelper> {
   public:
    explicit CallbackHelper(StarboardPlayer* player);

    void ClearDecoderBufferCache();
    void OnDecoderStatus(SbPlayer player, SbMediaType type,
                         SbPlayerDecoderState state, int ticket);
    void OnPlayerStatus(SbPlayer player, SbPlayerState state, int ticket);
    void OnDeallocateSample(const void* sample_buffer);
    void ResetPlayer();

   private:
    base::Lock lock_;
    StarboardPlayer* player_;
  };

  static const int64 kClearDecoderCacheIntervalInMilliseconds = 1000;

  // A map from raw data pointer returned by DecoderBuffer::GetData() to the
  // DecoderBuffer and a reference count.  The reference count indicates how
  // many instances of the DecoderBuffer is currently being decoded in the
  // pipeline.
  typedef std::map<const void*, std::pair<scoped_refptr<DecoderBuffer>, int> >
      DecodingBuffers;

  void CreatePlayer();
  void ClearDecoderBufferCache();

  void OnDecoderStatus(SbPlayer player, SbMediaType type,
                       SbPlayerDecoderState state, int ticket);
  void OnPlayerStatus(SbPlayer player, SbPlayerState state, int ticket);
  void OnDeallocateSample(const void* sample_buffer);

  static void DecoderStatusCB(SbPlayer player, void* context, SbMediaType type,
                              SbPlayerDecoderState state, int ticket);
  static void PlayerStatusCB(SbPlayer player, void* context,
                             SbPlayerState state, int ticket);
  static void DeallocateSampleCB(SbPlayer player, void* context,
                                 const void* sample_buffer);

#if SB_API_VERSION >= 4
  // Returns the output mode that should be used for a video with the given
  // specifications.
  static SbPlayerOutputMode ComputeSbPlayerOutputMode(
      SbMediaVideoCodec codec, SbDrmSystem drm_system,
      bool prefer_decode_to_texture);
#endif  // SB_API_VERSION >= 4

  // The following variables are initialized in the ctor and never changed.
  const scoped_refptr<base::MessageLoopProxy> message_loop_;
  scoped_refptr<CallbackHelper> callback_helper_;
  AudioDecoderConfig audio_config_;
  VideoDecoderConfig video_config_;
  const SbWindow window_;
  const SbDrmSystem drm_system_;
  Host* const host_;
  // Consider merge |SbPlayerSetBoundsHelper| into CallbackHelper.
  SbPlayerSetBoundsHelper* const set_bounds_helper_;

  // The following variables are only changed or accessed from the
  // |message_loop_|.
  int frame_width_;
  int frame_height_;
  DecodingBuffers decoding_buffers_;
  int ticket_;
  float volume_;
  double playback_rate_;
  bool paused_;
  bool seek_pending_;
  DecoderBufferCache decoder_buffer_cache_;
  // If |SetBounds| is called while we are in a suspended state, then the
  // |Rect| that we are passed will be saved to here, and then immediately set
  // on the new player that we construct when we are resumed.
  base::optional<gfx::Rect> pending_set_bounds_rect_;

  // The following variables can be accessed from GetInfo(), which can be called
  // from any threads.  So some of their usages have to be guarded by |lock_|.
  base::Lock lock_;
  State state_;
  SbPlayer player_;
  uint32 cached_video_frames_decoded_;
  uint32 cached_video_frames_dropped_;
  base::TimeDelta preroll_timestamp_;

#if SB_API_VERSION >= 4
  // Keep track of the output mode we are supposed to output to.
  SbPlayerOutputMode output_mode_;
#endif  // SB_API_VERSION >= 4
};

}  // namespace media
}  // namespace cobalt

#endif  // COBALT_MEDIA_BASE_STARBOARD_PLAYER_H_
