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

#include <Mfapi.h>
#include <Mferror.h>
#include <propvarutil.h>

#include <ios>
#include <sstream>
#include <utility>
#include <vector>

#include "starboard/common/log.h"
#include "starboard/shared/win32/error_utils.h"

namespace starboard {
namespace shared {
namespace win32 {

namespace {

#define MAKE_GUID_PAIR(X) std::pair<GUID, std::string>(X, #X)

const std::pair<GUID, std::string> kMfMtAudio[] = {
    MAKE_GUID_PAIR(MF_MT_AAC_PAYLOAD_TYPE),
    MAKE_GUID_PAIR(MF_MT_AUDIO_AVG_BYTES_PER_SECOND),
    MAKE_GUID_PAIR(MF_MT_AUDIO_BITS_PER_SAMPLE),
    MAKE_GUID_PAIR(MF_MT_AUDIO_BLOCK_ALIGNMENT),
    MAKE_GUID_PAIR(MF_MT_AUDIO_CHANNEL_MASK),
    MAKE_GUID_PAIR(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND),
    MAKE_GUID_PAIR(MF_MT_AUDIO_NUM_CHANNELS),
    MAKE_GUID_PAIR(MF_MT_AUDIO_SAMPLES_PER_BLOCK),
    MAKE_GUID_PAIR(MF_MT_AUDIO_SAMPLES_PER_SECOND),
    MAKE_GUID_PAIR(MF_MT_AUDIO_NUM_CHANNELS),
    MAKE_GUID_PAIR(MF_MT_MAJOR_TYPE),
    MAKE_GUID_PAIR(MF_MT_AUDIO_PREFER_WAVEFORMATEX),
    MAKE_GUID_PAIR(MF_MT_USER_DATA),
    MAKE_GUID_PAIR(MF_MT_SUBTYPE),
    MAKE_GUID_PAIR(MFAudioFormat_AAC),
    MAKE_GUID_PAIR(MFAudioFormat_ADTS),
    MAKE_GUID_PAIR(MFAudioFormat_ALAC),
    MAKE_GUID_PAIR(MFAudioFormat_AMR_NB),
    MAKE_GUID_PAIR(MFAudioFormat_AMR_WB),
    MAKE_GUID_PAIR(MFAudioFormat_AMR_WP),
    MAKE_GUID_PAIR(MFAudioFormat_Dolby_AC3),
    MAKE_GUID_PAIR(MFAudioFormat_Dolby_AC3_SPDIF),
    MAKE_GUID_PAIR(MFAudioFormat_Dolby_DDPlus),
    MAKE_GUID_PAIR(MFAudioFormat_DRM),
    MAKE_GUID_PAIR(MFAudioFormat_DTS),
    MAKE_GUID_PAIR(MFAudioFormat_FLAC),
    MAKE_GUID_PAIR(MFAudioFormat_Float),
    MAKE_GUID_PAIR(MFAudioFormat_Float_SpatialObjects),
    MAKE_GUID_PAIR(MFAudioFormat_MP3),
    MAKE_GUID_PAIR(MFAudioFormat_MPEG),
    MAKE_GUID_PAIR(MFAudioFormat_MSP1),
    MAKE_GUID_PAIR(MFAudioFormat_Opus),
    MAKE_GUID_PAIR(MFAudioFormat_PCM),
    MAKE_GUID_PAIR(MFAudioFormat_WMASPDIF),
    MAKE_GUID_PAIR(MFAudioFormat_WMAudio_Lossless),
    MAKE_GUID_PAIR(MFAudioFormat_WMAudioV8),
    MAKE_GUID_PAIR(MFAudioFormat_WMAudioV9),
    MAKE_GUID_PAIR(MFAudioFormat_WMAudioV9),
    MAKE_GUID_PAIR(MFMediaType_Audio),
};
#undef MAKE_GUID_PAIR

std::string GuidToFallbackString(GUID guid) {
  std::stringstream ss;
  wchar_t* guid_str = nullptr;
  StringFromCLSID(guid, &guid_str);
  ss << guid_str;
  CoTaskMemFree(guid_str);
  return ss.str();
}

std::string MfGuidToString(GUID guid) {
  const size_t n = sizeof(kMfMtAudio) / sizeof(*kMfMtAudio);
  for (auto i = 0; i < n; ++i) {
    const auto& elems = kMfMtAudio[i];
    if (guid == elems.first) {
      return elems.second;
    }
  }
  return GuidToFallbackString(guid);
}

std::string ImfAttributesToString(IMFAttributes* type) {
  std::stringstream ss;
  UINT32 n = 0;
  HRESULT hr = type->GetCount(&n);
  CheckResult(hr);
  for (UINT32 i = 0; i < n; ++i) {
    GUID key;
    PROPVARIANT val;
    type->GetItemByIndex(i, &key, &val);
    PropVariantClear(&val);

    MF_ATTRIBUTE_TYPE attrib_type;
    hr = type->GetItemType(key, &attrib_type);
    CheckResult(hr);

    std::string key_str = MfGuidToString(key);
    ss << key_str << ": ";

    switch (attrib_type) {
      case MF_ATTRIBUTE_GUID: {
        GUID value_guid;
        hr = type->GetGUID(key, &value_guid);
        ss << MfGuidToString(value_guid) << "\n";
        break;
      }

      case MF_ATTRIBUTE_DOUBLE: {
        double value = 0;
        hr = type->GetDouble(key, &value);
        ss << value << "\n";
        break;
      }

      case MF_ATTRIBUTE_BLOB: {
        // Skip.
        ss << "<BLOB>"
           << "\n";
        break;
      }

      case MF_ATTRIBUTE_UINT32: {
        UINT32 int_val = 0;
        hr = type->GetUINT32(key, &int_val);
        ss << int_val << "\n";
        break;
      }

      case MF_ATTRIBUTE_UINT64: {
        UINT64 int_val = 0;
        hr = type->GetUINT64(key, &int_val);
        ss << int_val << "\n";
        break;
      }

      case MF_ATTRIBUTE_STRING: {
        UINT32 length = 0;
        hr = type->GetStringLength(key, &length);
        CheckResult(hr);
        ++length;  // For trailing 0.
        std::vector<wchar_t> buffer(length);
        hr = type->GetString(key, buffer.data(), length, NULL);
        CheckResult(hr);
        ss << buffer.data() << "\n";
        break;
      }

      case MF_ATTRIBUTE_IUNKNOWN: {
        SB_NOTIMPLEMENTED();
        break;
      }
    }
  }
  ss << "\n";
  return ss.str();
}

}  // namespace.

void CopyProperties(IMFMediaType* source, IMFMediaType* destination) {
  UINT32 attribute_count = 0;
  HRESULT hr = source->GetCount(&attribute_count);
  CheckResult(hr);
  for (UINT32 i = 0; i < attribute_count; ++i) {
    GUID key;
    PROPVARIANT variant;
    hr = source->GetItemByIndex(i, &key, &variant);
    CheckResult(hr);
    PropVariantClear(&variant);

    MF_ATTRIBUTE_TYPE attrib_type;
    hr = source->GetItemType(key, &attrib_type);
    CheckResult(hr);

    switch (attrib_type) {
      case MF_ATTRIBUTE_GUID: {
        GUID value_guid;
        hr = source->GetGUID(key, &value_guid);
        CheckResult(hr);
        hr = destination->SetGUID(key, value_guid);
        CheckResult(hr);
        break;
      }

      case MF_ATTRIBUTE_DOUBLE: {
        double value = 0;
        hr = source->GetDouble(key, &value);
        CheckResult(hr);
        hr = destination->SetDouble(key, value);
        CheckResult(hr);
        break;
      }

      case MF_ATTRIBUTE_BLOB: {
        UINT32 blob_size = 0;
        hr = source->GetBlobSize(key, &blob_size);
        CheckResult(hr);
        std::vector<UINT8> blob(blob_size);
        hr = source->GetBlob(key, blob.data(), blob_size, &blob_size);
        CheckResult(hr);
        hr = destination->SetBlob(key, blob.data(), blob_size);
        CheckResult(hr);
        break;
      }

      case MF_ATTRIBUTE_UINT32: {
        UINT32 int_val = 0;
        hr = source->GetUINT32(key, &int_val);
        CheckResult(hr);
        hr = destination->SetUINT32(key, int_val);
        CheckResult(hr);
        break;
      }

      case MF_ATTRIBUTE_UINT64: {
        UINT64 int_val = 0;
        hr = source->GetUINT64(key, &int_val);
        CheckResult(hr);
        hr = destination->SetUINT64(key, int_val);
        CheckResult(hr);
        break;
      }

      case MF_ATTRIBUTE_STRING: {
        UINT32 length = 0;
        hr = source->GetStringLength(key, &length);
        CheckResult(hr);
        ++length;  // For trailing 0.
        std::vector<wchar_t> buffer(length);
        hr = source->GetString(key, buffer.data(), length, NULL);
        CheckResult(hr);
        hr = destination->SetString(key, buffer.data());
        CheckResult(hr);
        break;
      }

      case MF_ATTRIBUTE_IUNKNOWN: {
        SB_NOTIMPLEMENTED();
        break;
      }
    }
  }
}

std::ostream& operator<<(std::ostream& os, const IMFMediaType& media_type) {
  const IMFAttributes* attribs = &media_type;  // Upcast.
  std::string output_str =
      ImfAttributesToString(const_cast<IMFAttributes*>(attribs));
  os << output_str;
  return os;
}

}  // namespace win32
}  // namespace shared
}  // namespace starboard
