// Copyright 2017 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/media/media_util.h"

#include <algorithm>
#include <cctype>

#include "starboard/character.h"
#include "starboard/common/log.h"
#include "starboard/common/media.h"
#include "starboard/common/string.h"
#include "starboard/log.h"
#include "starboard/shared/starboard/media/codec_util.h"
#include "starboard/shared/starboard/media/mime_type.h"

namespace starboard {
namespace shared {
namespace starboard {
namespace media {

namespace {

const int64_t kDefaultBitRate = 0;
const int64_t kDefaultAudioChannels = 2;

template <typename StreamInfo>
void Assign(const StreamInfo& source, AudioStreamInfo* dest) {
  SB_DCHECK(dest);

  if (source.audio_specific_config_size > 0) {
    SB_DCHECK(source.audio_specific_config);
  }

  dest->codec = source.codec;

  if (dest->codec == kSbMediaAudioCodecNone) {
    dest->mime.clear();
    dest->audio_specific_config.clear();
    return;
  }

  SB_DCHECK(source.mime);

  dest->mime = source.mime;
  dest->number_of_channels = source.number_of_channels;
  dest->samples_per_second = source.samples_per_second;
  dest->bits_per_sample = source.bits_per_sample;

  auto config = static_cast<const uint8_t*>(source.audio_specific_config);
  dest->audio_specific_config.assign(
      config, config + source.audio_specific_config_size);
}

template <typename StreamInfo>
void Assign(const StreamInfo& source, VideoStreamInfo* dest) {
  SB_DCHECK(dest);

  dest->codec = source.codec;

  if (dest->codec == kSbMediaVideoCodecNone) {
    dest->mime.clear();
    dest->max_video_capabilities.clear();
    return;
  }

  SB_DCHECK(source.mime);
  SB_DCHECK(source.max_video_capabilities);

  dest->mime = source.mime;
  dest->max_video_capabilities = source.max_video_capabilities;
  dest->frame_width = source.frame_width;
  dest->frame_height = source.frame_height;
  dest->color_metadata = source.color_metadata;
}

template <typename StreamInfo>
void Assign(const AudioStreamInfo& source, StreamInfo* dest) {
  SB_DCHECK(dest);

  *dest = {};

  dest->codec = source.codec;
  dest->mime = source.mime.c_str();
  dest->number_of_channels = source.number_of_channels;
  dest->samples_per_second = source.samples_per_second;
  dest->bits_per_sample = source.bits_per_sample;
  if (!source.audio_specific_config.empty()) {
    dest->audio_specific_config = source.audio_specific_config.data();
    dest->audio_specific_config_size =
        static_cast<uint16_t>(source.audio_specific_config.size());
  }
}

template <typename StreamInfo>
void Assign(const VideoStreamInfo& source, StreamInfo* dest) {
  SB_DCHECK(dest);

  *dest = {};

  dest->codec = source.codec;
  dest->mime = source.mime.c_str();
  dest->max_video_capabilities = source.max_video_capabilities.c_str();
  dest->frame_width = source.frame_width;
  dest->frame_height = source.frame_height;
  dest->color_metadata = source.color_metadata;
}

}  // namespace

AudioStreamInfo& AudioStreamInfo::operator=(
    const SbMediaAudioStreamInfo& that) {
  Assign(that, this);
  return *this;
}

AudioStreamInfo& AudioStreamInfo::operator=(
    const CobaltExtensionEnhancedAudioMediaAudioStreamInfo& that) {
  Assign(that, this);
  return *this;
}

void AudioStreamInfo::ConvertTo(
    SbMediaAudioStreamInfo* audio_stream_info) const {
  Assign(*this, audio_stream_info);

#if SB_API_VERSION < SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  SB_DCHECK(audio_stream_info);
  audio_stream_info->format_tag = 0xff;
  audio_stream_info->block_alignment = 4;
  audio_stream_info->average_bytes_per_second =
      audio_stream_info->samples_per_second *
      audio_stream_info->number_of_channels *
      audio_stream_info->bits_per_sample / 8;
#endif  // SB_API_VERSION < SB_MEDIA_ENHANCED_AUDIO_API_VERSION
}

void AudioStreamInfo::ConvertTo(
    CobaltExtensionEnhancedAudioMediaAudioStreamInfo* audio_stream_info) const {
  Assign(*this, audio_stream_info);
}

bool operator==(const AudioStreamInfo& left, const AudioStreamInfo& right) {
  if (left.codec == kSbMediaAudioCodecNone &&
      right.codec == kSbMediaAudioCodecNone) {
    return true;
  }

  return left.codec == right.codec && left.mime == right.mime &&
         left.number_of_channels == right.number_of_channels &&
         left.samples_per_second == right.samples_per_second &&
         left.bits_per_sample == right.bits_per_sample &&
         left.audio_specific_config == right.audio_specific_config;
}

bool operator!=(const AudioStreamInfo& left, const AudioStreamInfo& right) {
  return !(left == right);
}

AudioSampleInfo& AudioSampleInfo::operator=(
    const SbMediaAudioSampleInfo& that) {
#if SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info = that.stream_info;
  discarded_duration_from_front = that.discarded_duration_from_front;
  discarded_duration_from_back = that.discarded_duration_from_back;
#else   // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info = that;
#endif  // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION

  return *this;
}

AudioSampleInfo& AudioSampleInfo::operator=(
    const CobaltExtensionEnhancedAudioMediaAudioSampleInfo& that) {
  stream_info = that.stream_info;
  discarded_duration_from_front = that.discarded_duration_from_front;
  discarded_duration_from_back = that.discarded_duration_from_back;
  return *this;
}

void AudioSampleInfo::ConvertTo(
    SbMediaAudioSampleInfo* audio_sample_info) const {
  SB_DCHECK(audio_sample_info);

  *audio_sample_info = {};
#if SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info.ConvertTo(&audio_sample_info->stream_info);
  audio_sample_info->discarded_duration_from_front =
      discarded_duration_from_front;
  audio_sample_info->discarded_duration_from_back =
      discarded_duration_from_back;
#else   // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info.ConvertTo(audio_sample_info);
#endif  // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
}

void AudioSampleInfo::ConvertTo(
    CobaltExtensionEnhancedAudioMediaAudioSampleInfo* audio_sample_info) const {
  SB_DCHECK(audio_sample_info);

  *audio_sample_info = {};
  stream_info.ConvertTo(&audio_sample_info->stream_info);
  audio_sample_info->discarded_duration_from_front =
      discarded_duration_from_front;
  audio_sample_info->discarded_duration_from_back =
      discarded_duration_from_back;
}

VideoStreamInfo& VideoStreamInfo::operator=(
    const SbMediaVideoStreamInfo& that) {
  Assign(that, this);
  return *this;
}

VideoStreamInfo& VideoStreamInfo::operator=(
    const CobaltExtensionEnhancedAudioMediaVideoStreamInfo& that) {
  Assign(that, this);
  return *this;
}

void VideoStreamInfo::ConvertTo(
    SbMediaVideoStreamInfo* video_stream_info) const {
  Assign(*this, video_stream_info);
}

void VideoStreamInfo::ConvertTo(
    CobaltExtensionEnhancedAudioMediaVideoStreamInfo* video_stream_info) const {
  Assign(*this, video_stream_info);
}

bool operator==(const VideoStreamInfo& left, const VideoStreamInfo& right) {
  if (left.codec == kSbMediaVideoCodecNone &&
      right.codec == kSbMediaVideoCodecNone) {
    return true;
  }

  return left.codec == right.codec && left.mime == right.mime &&
         left.max_video_capabilities == right.max_video_capabilities &&
         left.frame_width == right.frame_width &&
         left.frame_height == right.frame_height &&
         left.color_metadata == right.color_metadata;
}

bool operator!=(const VideoStreamInfo& left, const VideoStreamInfo& right) {
  return !(left == right);
}

VideoSampleInfo& VideoSampleInfo::operator=(
    const SbMediaVideoSampleInfo& that) {
#if SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info = that.stream_info;
#else   // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info = that;
#endif  // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  is_key_frame = that.is_key_frame;
  return *this;
}

VideoSampleInfo& VideoSampleInfo::operator=(
    const CobaltExtensionEnhancedAudioMediaVideoSampleInfo& that) {
  stream_info = that.stream_info;
  is_key_frame = that.is_key_frame;
  return *this;
}

void VideoSampleInfo::ConvertTo(
    SbMediaVideoSampleInfo* video_sample_info) const {
  SB_DCHECK(video_sample_info);

  *video_sample_info = {};
#if SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info.ConvertTo(&video_sample_info->stream_info);
#else   // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  stream_info.ConvertTo(video_sample_info);
#endif  // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  video_sample_info->is_key_frame = is_key_frame;
}

void VideoSampleInfo::ConvertTo(
    CobaltExtensionEnhancedAudioMediaVideoSampleInfo* video_sample_info) const {
  SB_DCHECK(video_sample_info);

  *video_sample_info = {};
  stream_info.ConvertTo(&video_sample_info->stream_info);
  video_sample_info->is_key_frame = is_key_frame;
}

std::ostream& operator<<(std::ostream& os, const VideoSampleInfo& sample_info) {
  const auto& stream_info = sample_info.stream_info;

  if (stream_info.codec == kSbMediaVideoCodecNone) {
    return os << "codec: " << GetMediaVideoCodecName(stream_info.codec);
  }

  os << "codec: " << GetMediaVideoCodecName(stream_info.codec) << ", ";
  os << "mime: " << stream_info.mime
     << ", max video capabilities: " << stream_info.max_video_capabilities
     << ", ";

  if (sample_info.is_key_frame) {
    os << "key frame, ";
  }

  os << stream_info.frame_width << 'x' << stream_info.frame_height << ' ';
  os << '(' << stream_info.color_metadata << ')';

  return os;
}

bool IsSDRVideo(int bit_depth,
                SbMediaPrimaryId primary_id,
                SbMediaTransferId transfer_id,
                SbMediaMatrixId matrix_id) {
  if (bit_depth != 8) {
    return false;
  }

  if (primary_id != kSbMediaPrimaryIdBt709 &&
      primary_id != kSbMediaPrimaryIdUnspecified &&
      primary_id != kSbMediaPrimaryIdSmpte170M) {
    return false;
  }

  if (transfer_id != kSbMediaTransferIdBt709 &&
      transfer_id != kSbMediaTransferIdUnspecified &&
      transfer_id != kSbMediaTransferIdSmpte170M) {
    return false;
  }

  if (matrix_id != kSbMediaMatrixIdBt709 &&
      matrix_id != kSbMediaMatrixIdUnspecified &&
      matrix_id != kSbMediaMatrixIdSmpte170M) {
    return false;
  }

  return true;
}

bool IsSDRVideo(const char* mime) {
  SB_DCHECK(mime);

  if (!mime) {
    SB_LOG(WARNING) << mime << " is empty, assuming sdr video.";
    return true;
  }

  MimeType mime_type(mime);
  if (!mime_type.is_valid()) {
    SB_LOG(WARNING) << mime << " is not a valid mime type, assuming sdr video.";
    return true;
  }
  const std::vector<std::string> codecs = mime_type.GetCodecs();
  if (codecs.empty()) {
    SB_LOG(WARNING) << mime << " contains no codecs, assuming sdr video.";
    return true;
  }
  if (codecs.size() > 1) {
    SB_LOG(WARNING) << mime
                    << " contains more than one codecs, assuming sdr video.";
    return true;
  }

  SbMediaVideoCodec video_codec;
  int profile = -1;
  int level = -1;
  int bit_depth = 8;
  SbMediaPrimaryId primary_id = kSbMediaPrimaryIdUnspecified;
  SbMediaTransferId transfer_id = kSbMediaTransferIdUnspecified;
  SbMediaMatrixId matrix_id = kSbMediaMatrixIdUnspecified;

  if (!ParseVideoCodec(codecs[0].c_str(), &video_codec, &profile, &level,
                       &bit_depth, &primary_id, &transfer_id, &matrix_id)) {
    SB_LOG(WARNING) << "ParseVideoCodec() failed on mime: " << mime
                    << ", assuming sdr video.";
    return true;
  }

  SB_DCHECK(video_codec != kSbMediaVideoCodecNone);
  // TODO: Consider to consolidate the two IsSDRVideo() implementations by
  //       calling IsSDRVideo(bit_depth, primary_id, transfer_id, matrix_id).
  return bit_depth == 8;
}

int GetBytesPerSample(SbMediaAudioSampleType sample_type) {
  switch (sample_type) {
    case kSbMediaAudioSampleTypeInt16Deprecated:
      return 2;
    case kSbMediaAudioSampleTypeFloat32:
      return 4;
  }

  SB_NOTREACHED();
  return 4;
}

std::string GetStringRepresentation(const uint8_t* data, const int size) {
  std::string result;

  for (int i = 0; i < size; ++i) {
    if (std::isspace(data[i])) {
      result += ' ';
    } else if (std::isprint(data[i])) {
      result += data[i];
    } else {
      result += '?';
    }
  }

  return result;
}

std::string GetMixedRepresentation(const uint8_t* data,
                                   const int size,
                                   const int bytes_per_line) {
  std::string result;

  for (int i = 0; i < size; i += bytes_per_line) {
    if (i + bytes_per_line <= size) {
      result += HexEncode(data + i, bytes_per_line);
      result += " | ";
      result += GetStringRepresentation(data + i, bytes_per_line);
      result += '\n';
    } else {
      int bytes_left = size - i;
      result += HexEncode(data + i, bytes_left);
      result += std::string((bytes_per_line - bytes_left) * 2, ' ');
      result += " | ";
      result += GetStringRepresentation(data + i, bytes_left);
      result += std::string(bytes_per_line - bytes_left, ' ');
      result += '\n';
    }
  }

  return result;
}

bool IsAudioSampleInfoSubstantiallyDifferent(const AudioStreamInfo& left,
                                             const AudioStreamInfo& right) {
  return left.codec != right.codec ||
         left.samples_per_second != right.samples_per_second ||
         left.number_of_channels != right.number_of_channels ||
         left.audio_specific_config != right.audio_specific_config;
}

int AudioDurationToFrames(SbTime duration, int samples_per_second) {
  SB_DCHECK(samples_per_second > 0)
      << "samples_per_second has to be greater than 0";
  // The same as `frames = (duration / kSbTimeSecond) * samples_per_second`,
  // switch order to avoid precision loss due to integer division.
  return duration * samples_per_second / kSbTimeSecond;
}

SbTime AudioFramesToDuration(int frames, int samples_per_second) {
  SB_DCHECK(samples_per_second > 0)
      << "samples_per_second has to be greater than 0";
  return frames * kSbTimeSecond / std::max(samples_per_second, 1);
}

}  // namespace media
}  // namespace starboard
}  // namespace shared
}  // namespace starboard

bool operator==(const SbMediaColorMetadata& metadata_1,
                const SbMediaColorMetadata& metadata_2) {
  return memcmp(&metadata_1, &metadata_2, sizeof(SbMediaColorMetadata)) == 0;
}

bool operator==(const SbMediaVideoSampleInfo& sample_info_1,
                const SbMediaVideoSampleInfo& sample_info_2) {
#if SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  const SbMediaVideoStreamInfo& stream_info_1 = sample_info_1.stream_info;
  const SbMediaVideoStreamInfo& stream_info_2 = sample_info_2.stream_info;
#else   // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
  const SbMediaVideoStreamInfo& stream_info_1 = sample_info_1;
  const SbMediaVideoStreamInfo& stream_info_2 = sample_info_2;
#endif  // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION

  if (stream_info_1.codec != stream_info_2.codec) {
    return false;
  }
  if (stream_info_1.codec == kSbMediaVideoCodecNone) {
    return true;
  }

  if (strcmp(stream_info_1.mime, stream_info_2.mime) != 0) {
    return false;
  }
  if (strcmp(stream_info_1.max_video_capabilities,
             stream_info_2.max_video_capabilities) != 0) {
    return false;
  }

  if (sample_info_1.is_key_frame != sample_info_2.is_key_frame) {
    return false;
  }
  if (stream_info_1.frame_width != stream_info_2.frame_width) {
    return false;
  }
  if (stream_info_1.frame_height != stream_info_2.frame_height) {
    return false;
  }
  return stream_info_1.color_metadata == stream_info_2.color_metadata;
}

#if SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION

bool operator==(const SbMediaVideoStreamInfo& stream_info_1,
                const SbMediaVideoStreamInfo& stream_info_2) {
  if (stream_info_1.codec != stream_info_2.codec) {
    return false;
  }
  if (stream_info_1.codec == kSbMediaVideoCodecNone) {
    return true;
  }

  if (strcmp(stream_info_1.mime, stream_info_2.mime) != 0) {
    return false;
  }
  if (strcmp(stream_info_1.max_video_capabilities,
             stream_info_2.max_video_capabilities) != 0) {
    return false;
  }
  if (stream_info_1.frame_width != stream_info_2.frame_width) {
    return false;
  }
  if (stream_info_1.frame_height != stream_info_2.frame_height) {
    return false;
  }
  return stream_info_1.color_metadata == stream_info_2.color_metadata;
}

#endif  // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION

bool operator!=(const SbMediaColorMetadata& metadata_1,
                const SbMediaColorMetadata& metadata_2) {
  return !(metadata_1 == metadata_2);
}

bool operator!=(const SbMediaVideoSampleInfo& sample_info_1,
                const SbMediaVideoSampleInfo& sample_info_2) {
  return !(sample_info_1 == sample_info_2);
}

#if SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
bool operator!=(const SbMediaVideoStreamInfo& stream_info_1,
                const SbMediaVideoStreamInfo& stream_info_2) {
  return !(stream_info_1 == stream_info_2);
}
#endif  // SB_API_VERSION >= SB_MEDIA_ENHANCED_AUDIO_API_VERSION
