// 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/file.h"
#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_
