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

#include "starboard/shared/starboard/player/video_dmp_writer.h"

#include <map>
#include <sstream>
#include <string>

#include "starboard/common/log.h"
#include "starboard/common/mutex.h"
#include "starboard/common/string.h"
#include "starboard/once.h"
#include "starboard/shared/starboard/application.h"

#if SB_HAS(PLAYER_FILTER_TESTS)
namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace video_dmp {

namespace {

using std::placeholders::_1;
using std::placeholders::_2;

class PlayerToWriterMap {
 public:
  PlayerToWriterMap()
      : dump_video_data_(Application::Get()->GetCommandLine()->HasSwitch(
            "dump_video_data")) {}
  bool dump_video_data() const { return dump_video_data_; }
  void Register(SbPlayer player) {
    ScopedLock scoped_lock(mutex_);
    SB_DCHECK(map_.find(player) == map_.end());
    map_[player] = new VideoDmpWriter;
  }
  void Unregister(SbPlayer player) {
    ScopedLock scoped_lock(mutex_);
    auto iter = map_.find(player);
    SB_DCHECK(iter != map_.end());
    delete iter->second;
    map_.erase(iter);
  }
  VideoDmpWriter* Get(SbPlayer player) {
    ScopedLock scoped_lock(mutex_);
    auto iter = map_.find(player);
    SB_DCHECK(iter != map_.end());
    return iter->second;
  }

 private:
  Mutex mutex_;
  bool dump_video_data_;
  std::map<SbPlayer, VideoDmpWriter*> map_;
};

SB_ONCE_INITIALIZE_FUNCTION(PlayerToWriterMap, GetOrCreatePlayerToWriterMap);

}  // namespace

VideoDmpWriter::VideoDmpWriter() : file_(kSbFileInvalid) {
  int index = 0;
  std::string file_name;
  while (!SbFileIsValid(file_)) {
    std::stringstream ss;
    ss << "video_" << index << ".dmp";
    file_name = ss.str();

    bool created = false;
    file_ = SbFileOpen(file_name.c_str(), kSbFileCreateOnly | kSbFileWrite,
                       &created, NULL);
    ++index;
  }
  SB_LOG(INFO) << "Dump video content to " << file_name;

  write_cb_ = std::bind(&VideoDmpWriter::WriteToFile, this, _1, _2);

  Write(write_cb_, kByteOrderMark);
  Write(write_cb_, kSupportWriterVersion);
}

VideoDmpWriter::~VideoDmpWriter() {
  SbFileClose(file_);
}

// static
void VideoDmpWriter::OnPlayerCreate(
    SbPlayer player,
    SbMediaAudioCodec audio_codec,
    SbMediaVideoCodec video_codec,
    SbDrmSystem drm_system,
    const SbMediaAudioSampleInfo* audio_sample_info) {
  // TODO: Allow dump of drm initialization data
  SB_UNREFERENCED_PARAMETER(drm_system);

  PlayerToWriterMap* map = GetOrCreatePlayerToWriterMap();
  if (!map->dump_video_data()) {
    return;
  }
  map->Register(player);
  VideoDmpWriter* dmp_writer = map->Get(player);
#if SB_API_VERSION < 11
  dmp_writer->audio_codec_ = audio_codec;
  dmp_writer->video_codec_ = video_codec;
#endif  // SB_API_VERSION < 11
  dmp_writer->DumpConfigs(video_codec, audio_codec, audio_sample_info);
}

// static
void VideoDmpWriter::OnPlayerWriteSample(
    SbPlayer player,
    const scoped_refptr<InputBuffer>& input_buffer) {
  PlayerToWriterMap* map = GetOrCreatePlayerToWriterMap();
  if (!map->dump_video_data()) {
    return;
  }
  map->Get(player)->DumpAccessUnit(input_buffer);
}

// static
void VideoDmpWriter::OnPlayerDestroy(SbPlayer player) {
  PlayerToWriterMap* map = GetOrCreatePlayerToWriterMap();
  if (!map->dump_video_data()) {
    return;
  }
  map->Unregister(player);
}

void VideoDmpWriter::DumpConfigs(
    SbMediaVideoCodec video_codec,
    SbMediaAudioCodec audio_codec,
    const SbMediaAudioSampleInfo* audio_sample_info) {
  Write(write_cb_, kRecordTypeAudioConfig);
  Write(write_cb_, audio_codec);
  if (audio_codec != kSbMediaAudioCodecNone) {
    SB_DCHECK(audio_sample_info);
    Write(write_cb_, audio_codec, *audio_sample_info);
  }

  Write(write_cb_, kRecordTypeVideoConfig);
  Write(write_cb_, video_codec);
}

void VideoDmpWriter::DumpAccessUnit(
    const scoped_refptr<InputBuffer>& input_buffer) {
  const SbMediaType& sample_type = input_buffer->sample_type();
  const void* sample_buffer = static_cast<const void*>(input_buffer->data());
  const int& sample_buffer_size = input_buffer->size();
  const SbTime& sample_timestamp = input_buffer->timestamp();
  const SbDrmSampleInfo* drm_sample_info = input_buffer->drm_info();

  if (sample_type == kSbMediaTypeAudio) {
    Write(write_cb_, kRecordTypeAudioAccessUnit);
  } else {
    SB_DCHECK(sample_type == kSbMediaTypeVideo);
    Write(write_cb_, kRecordTypeVideoAccessUnit);
  }

  Write(write_cb_, sample_timestamp);

  if (drm_sample_info && drm_sample_info->identifier_size == 16 &&
      (drm_sample_info->initialization_vector_size == 8 ||
       drm_sample_info->initialization_vector_size == 16)) {
    Write(write_cb_, true);
    Write(write_cb_, *drm_sample_info);
  } else {
    Write(write_cb_, false);
  }
  Write(write_cb_, static_cast<uint32_t>(sample_buffer_size));
  Write(write_cb_, sample_buffer, static_cast<size_t>(sample_buffer_size));

  if (sample_type == kSbMediaTypeAudio) {
    const SbMediaAudioSampleInfo& audio_sample_info =
        input_buffer->audio_sample_info();
#if SB_API_VERSION >= 11
    Write(write_cb_, audio_sample_info.codec, audio_sample_info);
#else   // SB_API_VERSION >= 11
    Write(write_cb_, audio_codec_, audio_sample_info);
#endif  // SB_API_VERSION >= 11
  } else {
    SB_DCHECK(sample_type == kSbMediaTypeVideo);
    const SbMediaVideoSampleInfo& video_sample_info =
        input_buffer->video_sample_info();
#if SB_API_VERSION >= 11
    Write(write_cb_, video_sample_info.codec, video_sample_info);
#else   // SB_API_VERSION >= 11
    Write(write_cb_, video_codec_, video_sample_info);
#endif  // SB_API_VERSION >= 11
  }
}

int VideoDmpWriter::WriteToFile(const void* buffer, int size) {
  return SbFileWrite(file_, static_cast<const char*>(buffer), size);
}

}  // namespace video_dmp
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
#endif  // SB_HAS(PLAYER_FILTER_TESTS)
