// Copyright 2022 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/mime_util.h"

#include <cstring>
#include <string>
#include <vector>

#include "starboard/common/log.h"
#include "starboard/common/media.h"
#include "starboard/log.h"
#include "starboard/shared/starboard/media/key_system_supportability_cache.h"
#include "starboard/shared/starboard/media/media_support_internal.h"
#include "starboard/shared/starboard/media/mime_supportability_cache.h"
#include "starboard/shared/starboard/media/mime_type.h"
#include "starboard/shared/starboard/media/parsed_mime_info.h"

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

namespace {

// Use SbMediaGetAudioConfiguration() to check if the platform can support
// |channels|.
bool IsAudioOutputSupported(SbMediaAudioCodingType coding_type, int channels) {
  // TODO(b/284140486, b/297426689): Consider removing the call to
  // `SbMediaGetAudioOutputCount()` completely as the loop will be terminated
  // once `SbMediaGetAudioConfiguration()` returns false.
  int count = SbMediaGetAudioOutputCount();

  for (int output_index = 0; output_index < count; ++output_index) {
    SbMediaAudioConfiguration configuration;
    if (!SbMediaGetAudioConfiguration(output_index, &configuration)) {
      break;
    }

    if (configuration.coding_type == coding_type &&
        configuration.number_of_channels >= channels) {
      return true;
    }
  }

  return false;
}

bool IsSupportedKeySystem(SbMediaAudioCodec codec, const char* key_system) {
  SB_DCHECK(key_system);
  // KeySystemSupportabilityCache() should always return supported for empty
  // |key_system|, so here it should always be non empty.
  SB_DCHECK(strlen(key_system) > 0);

  return SbMediaIsSupported(kSbMediaVideoCodecNone, codec, key_system);
}

bool IsSupportedKeySystem(SbMediaVideoCodec codec, const char* key_system) {
  SB_DCHECK(key_system);
  // KeySystemSupportabilityCache() should always return supported for empty
  // |key_system|, so here it should always be non empty.
  SB_DCHECK(strlen(key_system) > 0);

  return SbMediaIsSupported(codec, kSbMediaAudioCodecNone, key_system);
}

bool IsSupportedAudioCodec(const ParsedMimeInfo& mime_info) {
  SB_DCHECK(mime_info.is_valid());
  SB_DCHECK(mime_info.mime_type().is_valid());
  SB_DCHECK(mime_info.has_audio_info());

  const MimeType& mime_type = mime_info.mime_type();
  const ParsedMimeInfo::AudioCodecInfo& audio_info = mime_info.audio_info();

  switch (audio_info.codec) {
    case kSbMediaAudioCodecNone:
      SB_NOTREACHED();
      return false;
    case kSbMediaAudioCodecAac:
    case kSbMediaAudioCodecAc3:
    case kSbMediaAudioCodecEac3:
      if (mime_type.subtype() != "mp4") {
        return false;
      }
      break;
    case kSbMediaAudioCodecOpus:
    case kSbMediaAudioCodecVorbis:
      if (mime_type.subtype() != "webm") {
        return false;
      }
      break;
#if SB_API_VERSION >= 14
    case kSbMediaAudioCodecMp3:
      if (mime_type.subtype() != "mpeg" && mime_type.subtype() != "mp3") {
        return false;
      }
      break;
    case kSbMediaAudioCodecFlac:
      if (mime_type.subtype() != "ogg" && mime_type.subtype() != "flac") {
        return false;
      }
      break;
    case kSbMediaAudioCodecPcm:
      if (mime_type.subtype() != "wav") {
        return false;
      }
      break;
#endif  // SB_API_VERSION >= 14
#if SB_API_VERSION >= 15
    case kSbMediaAudioCodecIamf:
      if (mime_type.subtype() != "mp4") {
        return false;
      }
      break;
#endif  // SB_API_VERSION >= 15
  }

  if (!IsAudioOutputSupported(kSbMediaAudioCodingTypePcm,
                              audio_info.channels)) {
    return false;
  }

  return SbMediaIsAudioSupported(audio_info.codec, &mime_type,
                                 audio_info.bitrate);
}

bool IsSupportedVideoCodec(const ParsedMimeInfo& mime_info) {
  SB_DCHECK(mime_info.is_valid());
  SB_DCHECK(mime_info.mime_type().is_valid());
  SB_DCHECK(mime_info.has_video_info());

  const MimeType& mime_type = mime_info.mime_type();
  const ParsedMimeInfo::VideoCodecInfo& video_info = mime_info.video_info();

  switch (video_info.codec) {
    case kSbMediaVideoCodecNone:
      SB_NOTREACHED();
      return false;
    case kSbMediaVideoCodecH264:
    case kSbMediaVideoCodecH265:
      if (mime_type.subtype() != "mp4") {
        return false;
      }
      break;
    case kSbMediaVideoCodecMpeg2:
    case kSbMediaVideoCodecTheora:
      return false;  // No associated container in YT.
    case kSbMediaVideoCodecVc1:
    case kSbMediaVideoCodecAv1:
      if (mime_type.subtype() != "mp4") {
        return false;
      }
      break;
    case kSbMediaVideoCodecVp8:
      if (mime_type.subtype() != "webm") {
        return false;
      }
      break;
    case kSbMediaVideoCodecVp9:
      if (mime_type.subtype() != "mp4" && mime_type.subtype() != "webm") {
        return false;
      }
      break;
  }

  std::string cryptoblockformat =
      mime_type.GetParamStringValue("cryptoblockformat", "");
  if (!cryptoblockformat.empty()) {
    if ((mime_type.subtype() != "mp4" && mime_type.subtype() != "webm") ||
        cryptoblockformat != "subsample") {
      return false;
    }
  }

  return SbMediaIsVideoSupported(
      video_info.codec, &mime_type, video_info.profile, video_info.level,
      video_info.bit_depth, video_info.primary_id, video_info.transfer_id,
      video_info.matrix_id, video_info.frame_width, video_info.frame_height,
      video_info.bitrate, video_info.fps,
      video_info.decode_to_texture_required);
}

}  // namespace

SbMediaSupportType CanPlayMimeAndKeySystem(const char* mime,
                                           const char* key_system) {
  SB_DCHECK(mime);
  SB_DCHECK(key_system);

  // Get cached ParsedMimeInfo with its supportability. If it is not found in
  // the cache, MimeSupportabilityCache would parse the mime string and return
  // the ParsedMimeInfo with kSupportabilityUnknown.
  ParsedMimeInfo mime_info;
  Supportability mime_supportability =
      MimeSupportabilityCache::GetInstance()->GetMimeSupportability(mime,
                                                                    &mime_info);

  if (mime_info.disable_cache()) {
    // Disable all caches if required.
    mime_supportability = kSupportabilityUnknown;
    MimeSupportabilityCache::GetInstance()->SetCacheEnabled(false);
    KeySystemSupportabilityCache::GetInstance()->SetCacheEnabled(false);
  }

  // Reject mime if cached result is not supported.
  if (mime_supportability == kSupportabilityNotSupported) {
    return kSbMediaSupportTypeNotSupported;
  }

  // MimeSupportabilityCache::GetMimeSupportability() returns
  // kSupportabilityNotSupported if ParsedMimeInfo is not valid, so |mime_info|
  // must be valid here.
  SB_DCHECK(mime_info.is_valid());

  const MimeType& mime_type = mime_info.mime_type();
  const std::vector<std::string>& codecs = mime_type.GetCodecs();

  // Quick check for mp4 format.
  if (codecs.size() == 0) {
    // This happens when the H5 player is either querying for progressive
    // playback support, or probing for generic mp4 support without specific
    // codecs.
    if (mime_type.subtype() == "mp4") {
      return kSbMediaSupportTypeMaybe;
    } else {
      return kSbMediaSupportTypeNotSupported;
    }
  }

  // Reject mime if it doesn't have any valid codec info.
  if (!mime_info.has_audio_info() && !mime_info.has_video_info()) {
    return kSbMediaSupportTypeNotSupported;
  }

  // Get cached key system supportability. Note that we check if audio or video
  // codec supports key system separately.
  if (mime_info.has_audio_info()) {
    Supportability key_system_supportability =
        KeySystemSupportabilityCache::GetInstance()->GetKeySystemSupportability(
            mime_info.audio_info().codec, key_system);
    if (key_system_supportability == kSupportabilityUnknown) {
      key_system_supportability =
          IsSupportedKeySystem(mime_info.audio_info().codec, key_system)
              ? kSupportabilitySupported
              : kSupportabilityNotSupported;
      KeySystemSupportabilityCache::GetInstance()->CacheKeySystemSupportability(
          mime_info.audio_info().codec, key_system, key_system_supportability);
    }
    // Reject mime if audio codec doesn't support the key system.
    if (key_system_supportability == kSupportabilityNotSupported) {
      return kSbMediaSupportTypeNotSupported;
    }
  }
  if (mime_info.has_video_info()) {
    Supportability key_system_supportability =
        KeySystemSupportabilityCache::GetInstance()->GetKeySystemSupportability(
            mime_info.video_info().codec, key_system);
    if (key_system_supportability == kSupportabilityUnknown) {
      key_system_supportability =
          IsSupportedKeySystem(mime_info.video_info().codec, key_system)
              ? kSupportabilitySupported
              : kSupportabilityNotSupported;
      KeySystemSupportabilityCache::GetInstance()->CacheKeySystemSupportability(
          mime_info.video_info().codec, key_system, key_system_supportability);
    }
    // Reject mime if video codec doesn't the key system.
    if (key_system_supportability == kSupportabilityNotSupported) {
      return kSbMediaSupportTypeNotSupported;
    }
  }

  // At this point, |key_system| is supported. Return supported here if
  // mime is also supported. Otherwise, |mime_supportability| must be unknown.
  if (mime_supportability == kSupportabilitySupported) {
    return kSbMediaSupportTypeProbably;
  }
  SB_DCHECK(mime_supportability == kSupportabilityUnknown);

  // Call platform functions to check if it's supported.
  if (mime_info.has_audio_info() && !IsSupportedAudioCodec(mime_info)) {
    mime_supportability = kSupportabilityNotSupported;
  } else if (mime_info.has_video_info() && !IsSupportedVideoCodec(mime_info)) {
    mime_supportability = kSupportabilityNotSupported;
  } else {
    mime_supportability = kSupportabilitySupported;
  }

  // Cache mime supportability.
  MimeSupportabilityCache::GetInstance()->CacheMimeSupportability(
      mime, mime_supportability);

  return mime_supportability == kSupportabilitySupported
             ? kSbMediaSupportTypeProbably
             : kSbMediaSupportTypeNotSupported;
}

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