// Copyright 2017 Google Inc. 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.

// Not breaking these functions up because however one is implemented, the
// others should be implemented similarly.

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

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

#include <utility>

#include "starboard/log.h"
#include "starboard/shared/win32/wchar_utils.h"

namespace starboard {
namespace shared {
namespace win32 {
namespace {

std::string GetFormatHresultMessage(HRESULT hr) {
  std::stringstream ss;
  LPWSTR error_message;
  int message_size = FormatMessage(
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
          FORMAT_MESSAGE_IGNORE_INSERTS,
      nullptr,  // Unused with FORMAT_MESSAGE_FROM_SYSTEM.
      hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR)&error_message,
      0,  // Minimum size for output buffer.
      nullptr);
  SB_DCHECK(message_size);
  ss << wchar_tToUTF8(error_message);
  LocalFree(error_message);
  return ss.str();
}


#define MAKE_HR_PAIR(X) std::pair<HRESULT, std::string>(X, #X)
const std::pair<HRESULT, std::string> kHresultValueStrings[] = {
  MAKE_HR_PAIR(S_OK),
  MAKE_HR_PAIR(MF_E_PLATFORM_NOT_INITIALIZED),
  MAKE_HR_PAIR(MF_E_BUFFERTOOSMALL),
  MAKE_HR_PAIR(MF_E_INVALIDREQUEST),
  MAKE_HR_PAIR(MF_E_INVALIDSTREAMNUMBER),
  MAKE_HR_PAIR(MF_E_INVALIDMEDIATYPE),
  MAKE_HR_PAIR(MF_E_NOTACCEPTING),
  MAKE_HR_PAIR(MF_E_NOT_INITIALIZED),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_REPRESENTATION),
  MAKE_HR_PAIR(MF_E_NO_MORE_TYPES),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_SERVICE),
  MAKE_HR_PAIR(MF_E_UNEXPECTED),
  MAKE_HR_PAIR(MF_E_INVALIDNAME),
  MAKE_HR_PAIR(MF_E_INVALIDTYPE),
  MAKE_HR_PAIR(MF_E_INVALID_FILE_FORMAT),
  MAKE_HR_PAIR(MF_E_INVALIDINDEX),
  MAKE_HR_PAIR(MF_E_INVALID_TIMESTAMP),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_SCHEME),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_BYTESTREAM_TYPE),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_TIME_FORMAT),
  MAKE_HR_PAIR(MF_E_NO_SAMPLE_TIMESTAMP),
  MAKE_HR_PAIR(MF_E_NO_SAMPLE_DURATION),
  MAKE_HR_PAIR(MF_E_INVALID_STREAM_DATA),
  MAKE_HR_PAIR(MF_E_RT_UNAVAILABLE),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_RATE),
  MAKE_HR_PAIR(MF_E_THINNING_UNSUPPORTED),
  MAKE_HR_PAIR(MF_E_REVERSE_UNSUPPORTED),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_RATE_TRANSITION),
  MAKE_HR_PAIR(MF_E_RATE_CHANGE_PREEMPTED),
  MAKE_HR_PAIR(MF_E_NOT_FOUND),
  MAKE_HR_PAIR(MF_E_NOT_AVAILABLE),
  MAKE_HR_PAIR(MF_E_NO_CLOCK),
  MAKE_HR_PAIR(MF_S_MULTIPLE_BEGIN),
  MAKE_HR_PAIR(MF_E_MULTIPLE_BEGIN),
  MAKE_HR_PAIR(MF_E_MULTIPLE_SUBSCRIBERS),
  MAKE_HR_PAIR(MF_E_TIMER_ORPHANED),
  MAKE_HR_PAIR(MF_E_STATE_TRANSITION_PENDING),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_STATE_TRANSITION),
  MAKE_HR_PAIR(MF_E_UNRECOVERABLE_ERROR_OCCURRED),
  MAKE_HR_PAIR(MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS),
  MAKE_HR_PAIR(MF_E_SAMPLE_NOT_WRITABLE),
  MAKE_HR_PAIR(MF_E_INVALID_KEY),
  MAKE_HR_PAIR(MF_E_BAD_STARTUP_VERSION),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_CAPTION),
  MAKE_HR_PAIR(MF_E_INVALID_POSITION),
  MAKE_HR_PAIR(MF_E_ATTRIBUTENOTFOUND),
  MAKE_HR_PAIR(MF_E_PROPERTY_TYPE_NOT_ALLOWED),
  MAKE_HR_PAIR(MF_E_TOPO_INVALID_OPTIONAL_NODE),
  MAKE_HR_PAIR(MF_E_TOPO_CANNOT_FIND_DECRYPTOR),
  MAKE_HR_PAIR(MF_E_TOPO_CODEC_NOT_FOUND),
  MAKE_HR_PAIR(MF_E_TOPO_CANNOT_CONNECT),
  MAKE_HR_PAIR(MF_E_TOPO_UNSUPPORTED),
  MAKE_HR_PAIR(MF_E_TOPO_INVALID_TIME_ATTRIBUTES),
  MAKE_HR_PAIR(MF_E_TOPO_LOOPS_IN_TOPOLOGY),
  MAKE_HR_PAIR(MF_E_TOPO_MISSING_PRESENTATION_DESCRIPTOR),
  MAKE_HR_PAIR(MF_E_TOPO_MISSING_STREAM_DESCRIPTOR),
  MAKE_HR_PAIR(MF_E_TOPO_STREAM_DESCRIPTOR_NOT_SELECTED),
  MAKE_HR_PAIR(MF_E_TOPO_MISSING_SOURCE),
  MAKE_HR_PAIR(MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED),
  MAKE_HR_PAIR(MF_E_TRANSFORM_TYPE_NOT_SET),
  MAKE_HR_PAIR(MF_E_TRANSFORM_STREAM_CHANGE),
  MAKE_HR_PAIR(MF_E_TRANSFORM_INPUT_REMAINING),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROFILE_MISSING),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROFILE_INVALID_OR_CORRUPT),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROFILE_TRUNCATED),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROPERTY_PID_NOT_RECOGNIZED),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROPERTY_VARIANT_TYPE_WRONG),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROPERTY_NOT_WRITEABLE),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROPERTY_ARRAY_VALUE_WRONG_NUM_DIM),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROPERTY_VALUE_SIZE_WRONG),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROPERTY_VALUE_OUT_OF_RANGE),
  MAKE_HR_PAIR(MF_E_TRANSFORM_PROPERTY_VALUE_INCOMPATIBLE),
  MAKE_HR_PAIR(MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_OUTPUT_MEDIATYPE),
  MAKE_HR_PAIR(MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_INPUT_MEDIATYPE),
  MAKE_HR_PAIR(MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION),
  MAKE_HR_PAIR(MF_E_TRANSFORM_CONFLICTS_WITH_OTHER_CURRENTLY_ENABLED_FEATURES),
  MAKE_HR_PAIR(MF_E_TRANSFORM_NEED_MORE_INPUT),
  MAKE_HR_PAIR(MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_SPKR_CONFIG),
  MAKE_HR_PAIR(MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING),
  MAKE_HR_PAIR(MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENT),
  MAKE_HR_PAIR(MF_E_UNSUPPORTED_D3D_TYPE),
  MAKE_HR_PAIR(MF_E_TRANSFORM_ASYNC_LOCKED),
  MAKE_HR_PAIR(MF_E_TRANSFORM_CANNOT_INITIALIZE_ACM_DRIVER),
};
#undef MAKE_HR_PAIR

bool FindHResultEnumString(HRESULT hr, std::string* output) {
  const size_t n = sizeof(kHresultValueStrings) /
                   sizeof(*kHresultValueStrings);

  for (auto i = 0; i < n; ++i) {
    const auto& elems = kHresultValueStrings[i];
    if (hr == elems.first) {
      *output = elems.second;
      return true;
    }
  }
  return false;
}

}

std::ostream& operator<<(std::ostream& os, const Win32ErrorCode& error_code) {
  LPWSTR error_message;
  int message_size = FormatMessage(
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
          FORMAT_MESSAGE_IGNORE_INSERTS,
      nullptr,  // Unused with FORMAT_MESSAGE_FROM_SYSTEM.
      error_code.GetHRESULT(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR)&error_message,
      0,  // Minimum size for output buffer.
      nullptr);
  SB_DCHECK(message_size);
  os << wchar_tToUTF8(error_message);
  LocalFree(error_message);

  return os;
}

void DebugLogWinError() {
#if defined(_DEBUG)
  DWORD error_code = GetLastError();
  if (!error_code)
    return;

  SB_LOG(ERROR) << Win32ErrorCode(error_code);
#endif  // defined(_DEBUG)
}

std::string HResultToString(HRESULT hr) {
  std::string enum_str;
  bool has_enum_str = FindHResultEnumString(hr, &enum_str);
  std::string error_message = GetFormatHresultMessage(hr);

  std::stringstream ss;
  if (has_enum_str) {
    ss << enum_str << ": ";
  }

  ss << "\"" << error_message << "\"";
  return ss.str();
}

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