// 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_reader.h"

#include <functional>

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

namespace {

template <typename AccessUnit>
int64_t CalculateAverageBitrate(const std::vector<AccessUnit>& access_units) {
  if (access_units.empty()) {
    return 0;
  }

  if (access_units.size() == 1) {
    // A guestimated bitrate of 1k.
    return 1024;
  }

  SbTime duration =
      access_units.back().timestamp() - access_units.front().timestamp();

  SB_DCHECK(duration > 0);

  int64_t total_bitrate = 0;
  for (auto& au : access_units) {
    total_bitrate += au.data().size();
  }

  return total_bitrate * 8 * kSbTimeSecond / duration;
}

static void DeallocateSampleFunc(SbPlayer player,
                                 void* context,
                                 const void* sample_buffer) {
  SB_UNREFERENCED_PARAMETER(player);
  SB_UNREFERENCED_PARAMETER(context);
  SB_UNREFERENCED_PARAMETER(sample_buffer);
}

SbPlayerSampleInfo ConvertToPlayerSampleInfo(
    const VideoDmpReader::AudioAccessUnit& audio_unit) {
  SbPlayerSampleInfo sample_info = {};
  sample_info.buffer = audio_unit.data().data();
  sample_info.buffer_size = static_cast<int>(audio_unit.data().size());
  sample_info.timestamp = audio_unit.timestamp();
  sample_info.drm_info = audio_unit.drm_sample_info();
#if SB_API_VERSION >= 11
  sample_info.type = kSbMediaTypeAudio;
  sample_info.audio_sample_info = audio_unit.audio_sample_info();
#else   // SB_API_VERSION >= 11
  sample_info.video_sample_info = NULL;
#endif  // SB_API_VERSION >= 11
  return sample_info;
}

SbPlayerSampleInfo ConvertToPlayerSampleInfo(
    const VideoDmpReader::VideoAccessUnit& video_unit) {
  SbPlayerSampleInfo sample_info = {};
  sample_info.buffer = video_unit.data().data();
  sample_info.buffer_size = static_cast<int>(video_unit.data().size());
  sample_info.timestamp = video_unit.timestamp();
  sample_info.drm_info = video_unit.drm_sample_info();
#if SB_API_VERSION >= 11
  sample_info.type = kSbMediaTypeVideo;
  sample_info.video_sample_info = video_unit.video_sample_info();
#else   // SB_API_VERSION >= 11
  sample_info.video_sample_info = &video_unit.video_sample_info();
#endif  // SB_API_VERSION >= 11
  return sample_info;
}

}  // namespace

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

VideoDmpReader::VideoDmpReader(const char* filename)
    : reverse_byte_order_(false),
      read_cb_(std::bind(&VideoDmpReader::ReadFromCache, this, _1, _2)) {
  ScopedFile file(filename, kSbFileOpenOnly | kSbFileRead);
  SB_CHECK(file.IsValid()) << "Failed to open " << filename;
  int64_t file_size = file.GetSize();
  SB_CHECK(file_size >= 0);

  file_cache_.resize(file_size);
  int bytes_read = file.ReadAll(file_cache_.data(), file_size);
  SB_CHECK(bytes_read == file_size);

  Parse();

  // To free memory used by |file_cache_|.
  decltype(file_cache_) empty;
  file_cache_.swap(empty);
}

VideoDmpReader::~VideoDmpReader() {}

SbPlayerSampleInfo VideoDmpReader::GetPlayerSampleInfo(SbMediaType type,
                                                       size_t index) const {
  switch (type) {
    case kSbMediaTypeAudio: {
      SB_DCHECK(index < audio_access_units_.size());
      const AudioAccessUnit& audio_au = audio_access_units_[index];
      return ConvertToPlayerSampleInfo(audio_au);
    }
    case kSbMediaTypeVideo: {
      SB_DCHECK(index < video_access_units_.size());
      const VideoAccessUnit& video_au = video_access_units_[index];
      return ConvertToPlayerSampleInfo(video_au);
    }
  }
  SB_NOTREACHED() << "Unhandled SbMediaType";
  return SbPlayerSampleInfo();
}

SbMediaAudioSampleInfo VideoDmpReader::GetAudioSampleInfo(size_t index) const {
  SB_DCHECK(index < audio_access_units_.size());
  const AudioAccessUnit& au = audio_access_units_[index];
  return au.audio_sample_info();
}

void VideoDmpReader::Parse() {
  reverse_byte_order_ = false;
  uint32_t byte_order_mark;
  Read(read_cb_, reverse_byte_order_, &byte_order_mark);
  if (byte_order_mark != kByteOrderMark) {
    std::reverse(reinterpret_cast<uint8_t*>(&byte_order_mark),
                 reinterpret_cast<uint8_t*>(&byte_order_mark + 1));
    SB_DCHECK(byte_order_mark == kByteOrderMark);
    if (byte_order_mark != kByteOrderMark) {
      SB_LOG(ERROR) << "Invalid BOM" << byte_order_mark;
      return;
    }
    reverse_byte_order_ = true;
  }
  uint32_t dmp_writer_version;
  Read(read_cb_, reverse_byte_order_, &dmp_writer_version);
  if (dmp_writer_version != kSupportWriterVersion) {
    SB_LOG(ERROR) << "Unsupported input dmp file(" << dmp_writer_version
                  << "). Please regenerate dmp files with"
                  << " right dmp writer. Currently support version "
                  << kSupportWriterVersion << ".";
    return;
  }
  for (;;) {
    uint32_t type;
    int bytes_read = ReadFromCache(&type, sizeof(type));
    if (bytes_read <= 0) {
      break;
    }
    if (reverse_byte_order_) {
      std::reverse(reinterpret_cast<uint8_t*>(&type),
                   reinterpret_cast<uint8_t*>(&type + 1));
    }
    switch (type) {
      case kRecordTypeAudioConfig:
        Read(read_cb_, reverse_byte_order_, &audio_codec_);
        if (audio_codec_ != kSbMediaAudioCodecNone) {
          Read(read_cb_, reverse_byte_order_, &audio_sample_info_);
        }
        break;
      case kRecordTypeVideoConfig:
        Read(read_cb_, reverse_byte_order_, &video_codec_);
        break;
      case kRecordTypeAudioAccessUnit:
        audio_access_units_.push_back(ReadAudioAccessUnit());
        break;
      case kRecordTypeVideoAccessUnit:
        video_access_units_.push_back(ReadVideoAccessUnit());
        break;
      default:
        SB_NOTREACHED() << type;
        break;
    }
  }
  audio_bitrate_ = CalculateAverageBitrate(audio_access_units_);
  video_bitrate_ = CalculateAverageBitrate(video_access_units_);

  // Guestimate the video fps.
  if (video_access_units_.size() > 1) {
    SbTime first_timestamp = video_access_units_.front().timestamp();
    SbTime second_timestamp = video_access_units_.back().timestamp();
    for (const auto& au : video_access_units_) {
      if (au.timestamp() != first_timestamp &&
          au.timestamp() < second_timestamp) {
        second_timestamp = au.timestamp();
      }
    }
    SB_DCHECK(first_timestamp < second_timestamp);
    video_fps_ = kSbTimeSecond / (second_timestamp - first_timestamp);
  }
}

VideoDmpReader::AudioAccessUnit VideoDmpReader::ReadAudioAccessUnit() {
  SbTime timestamp;
  Read(read_cb_, reverse_byte_order_, &timestamp);

  bool drm_sample_info_present;
  Read(read_cb_, reverse_byte_order_, &drm_sample_info_present);

  SbDrmSampleInfoWithSubSampleMapping drm_sample_info;
  if (drm_sample_info_present) {
    Read(read_cb_, reverse_byte_order_, &drm_sample_info);
  }

  uint32_t size;
  Read(read_cb_, reverse_byte_order_, &size);
  std::vector<uint8_t> data(size);
  Read(read_cb_, data.data(), size);

  SbMediaAudioSampleInfoWithConfig audio_sample_info;
  Read(read_cb_, reverse_byte_order_, &audio_sample_info);

  return AudioAccessUnit(timestamp,
                         drm_sample_info_present ? &drm_sample_info : NULL,
                         std::move(data), audio_sample_info);
}

VideoDmpReader::VideoAccessUnit VideoDmpReader::ReadVideoAccessUnit() {
  SbTime timestamp;
  Read(read_cb_, reverse_byte_order_, &timestamp);

  bool drm_sample_info_present;
  Read(read_cb_, reverse_byte_order_, &drm_sample_info_present);

  SbDrmSampleInfoWithSubSampleMapping drm_sample_info;
  if (drm_sample_info_present) {
    Read(read_cb_, reverse_byte_order_, &drm_sample_info);
  }

  uint32_t size;
  Read(read_cb_, reverse_byte_order_, &size);
  std::vector<uint8_t> data(size);
  Read(read_cb_, data.data(), size);

  SbMediaVideoSampleInfoWithOptionalColorMetadata video_sample_info;
  Read(read_cb_, reverse_byte_order_, &video_sample_info);

  return VideoAccessUnit(timestamp,
                         drm_sample_info_present ? &drm_sample_info : NULL,
                         std::move(data), video_sample_info);
}

int VideoDmpReader::ReadFromCache(void* buffer, int bytes_to_read) {
  bytes_to_read = std::min(
      bytes_to_read, static_cast<int>(file_cache_.size()) - file_cache_offset_);
  SbMemoryCopy(buffer, file_cache_.data() + file_cache_offset_, bytes_to_read);
  file_cache_offset_ += bytes_to_read;
  return bytes_to_read;
}

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