// Copyright 2018 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 STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_DMP_READER_H_
#define STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_DMP_READER_H_

#include <map>
#include <string>
#include <vector>

#include "starboard/common/log.h"
#include "starboard/common/mutex.h"
#include "starboard/common/optional.h"
#include "starboard/common/ref_counted.h"
#include "starboard/media.h"
#include "starboard/player.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/player/file_cache_reader.h"
#include "starboard/shared/starboard/player/video_dmp_common.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace video_dmp {

class VideoDmpReader {
 public:
  enum ReadOnDemandOptions {
    kDisableReadOnDemand,
    kEnableReadOnDemand,
  };

  class AccessUnit {
   public:
    AccessUnit(SbTime timestamp,
               const SbDrmSampleInfoWithSubSampleMapping* drm_sample_info,
               std::vector<uint8_t> data)
        : timestamp_(timestamp),
          drm_sample_info_present_(drm_sample_info != NULL),
          drm_sample_info_(drm_sample_info == NULL
                               ? SbDrmSampleInfoWithSubSampleMapping()
                               : *drm_sample_info),
          data_(std::move(data)) {}
    SbTime timestamp() const { return timestamp_; }
    const SbDrmSampleInfo* drm_sample_info() const {
      return drm_sample_info_present_ ? &drm_sample_info_ : NULL;
    }
    const std::vector<uint8_t>& data() const { return data_; }

   private:
    SbTime timestamp_;
    bool drm_sample_info_present_;
    SbDrmSampleInfoWithSubSampleMapping drm_sample_info_;
    std::vector<uint8_t> data_;
  };

  class AudioAccessUnit : public AccessUnit {
   public:
    AudioAccessUnit(SbTime timestamp,
                    const SbDrmSampleInfoWithSubSampleMapping* drm_sample_info,
                    std::vector<uint8_t> data,
                    const SbMediaAudioSampleInfoWithConfig& audio_sample_info)
        : AccessUnit(timestamp, drm_sample_info, std::move(data)),
          audio_sample_info_(audio_sample_info) {}
    const SbMediaAudioSampleInfo& audio_sample_info() const {
      return audio_sample_info_;
    }

   private:
    SbMediaAudioSampleInfoWithConfig audio_sample_info_;
  };

  class VideoAccessUnit : public AccessUnit {
   public:
    VideoAccessUnit(SbTime timestamp,
                    const SbDrmSampleInfoWithSubSampleMapping* drm_sample_info,
                    std::vector<uint8_t> data,
                    const SbMediaVideoSampleInfoWithOptionalColorMetadata&
                        video_sample_info)
        : AccessUnit(timestamp, drm_sample_info, std::move(data)),
          video_sample_info_(video_sample_info) {}
    const SbMediaVideoSampleInfo& video_sample_info() const {
      return video_sample_info_;
    }

   private:
    SbMediaVideoSampleInfoWithOptionalColorMetadata video_sample_info_;
  };

  explicit VideoDmpReader(
      const char* filename,
      ReadOnDemandOptions read_on_demand_options = kDisableReadOnDemand);
  ~VideoDmpReader();

  SbMediaAudioCodec audio_codec() const { return dmp_info_.audio_codec; }
  const SbMediaAudioSampleInfo& audio_sample_info() const {
    return dmp_info_.audio_sample_info;
  }
  int64_t audio_bitrate() const { return dmp_info_.audio_bitrate; }

  SbMediaVideoCodec video_codec() const { return dmp_info_.video_codec; }
  int64_t video_bitrate() const { return dmp_info_.video_bitrate; }
  int video_fps() const { return dmp_info_.video_fps; }

  size_t number_of_audio_buffers() const {
    return dmp_info_.audio_access_units_size;
  }
  size_t number_of_video_buffers() const {
    return dmp_info_.video_access_units_size;
  }

  SbPlayerSampleInfo GetPlayerSampleInfo(SbMediaType type, size_t index);
  const SbMediaAudioSampleInfo& GetAudioSampleInfo(size_t index);

 private:
  struct DmpInfo {
    SbMediaAudioCodec audio_codec = kSbMediaAudioCodecNone;
    SbMediaAudioSampleInfoWithConfig audio_sample_info;
    size_t audio_access_units_size = 0;
    int64_t audio_bitrate = 0;

    SbMediaVideoCodec video_codec = kSbMediaVideoCodecNone;
    size_t video_access_units_size = 0;
    int64_t video_bitrate = 0;
    int video_fps = 0;
  };

  class Registry {
   public:
    bool GetDmpInfo(const char* filename, DmpInfo* dmp_info) const;
    void Register(const char* filename, const DmpInfo& dmp_info);

   private:
    Mutex mutex_;
    std::map<std::string, DmpInfo> dmp_infos_;
  };

  VideoDmpReader(const VideoDmpReader&) = delete;
  VideoDmpReader& operator=(const VideoDmpReader&) = delete;

  void ParseHeader(uint32_t* dmp_writer_version);
  bool ParseOneRecord();
  void Parse();
  void EnsureSampleLoaded(SbMediaType type, size_t index);

  AudioAccessUnit ReadAudioAccessUnit();
  VideoAccessUnit ReadVideoAccessUnit();
  static Registry* GetRegistry();

  const bool allow_read_on_demand_;

  FileCacheReader file_reader_;
  ReadCB read_cb_;
  DmpInfo dmp_info_;

  optional<bool> reverse_byte_order_;

  std::vector<AudioAccessUnit> audio_access_units_;
  std::vector<VideoAccessUnit> video_access_units_;
};

}  // namespace video_dmp
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard

#endif  // STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_DMP_READER_H_
