// 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.

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

#include <winsock2.h>

#include <iphlpapi.h>

#include <memory>

#include "starboard/log.h"
#include "starboard/shared/win32/socket_internal.h"
#include "starboard/socket.h"

namespace {
const ULONG kDefaultAdapterInfoBufferSizeInBytes = 16 * 1024;
}  // namespace

namespace starboard {
namespace shared {
namespace win32 {

bool GetAdapters(const SbSocketAddressType address_type,
                 std::unique_ptr<char[]>* adapter_info) {
  SB_DCHECK(adapter_info);

  ULONG family = 0;
  int address_length_bytes = 0;

  switch (address_type) {
    case kSbSocketAddressTypeIpv4:
      family = AF_INET;
      address_length_bytes = kAddressLengthIpv4;
      break;
    case kSbSocketAddressTypeIpv6:
      family = AF_INET6;
      address_length_bytes = kAddressLengthIpv6;
      break;
    default:
      SB_NOTREACHED() << "Invalid address type: " << address_type;
      return false;
  }

  ULONG adapter_addresses_number_bytes = kDefaultAdapterInfoBufferSizeInBytes;

  for (int try_count = 0; try_count != 2; ++try_count) {
    // Using auto for return value here, since different versions of windows use
    // slightly different datatypes.  These differences do not matter to us, but
    // the compiler might warn on them.
    adapter_info->reset(new char[adapter_addresses_number_bytes]);
    PIP_ADAPTER_ADDRESSES adapter_addresses =
        reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_info->get());

    // Note: If |GetAdapterAddresses| deems that buffer supplied is not enough,
    // it will return the recommended number of bytes in
    // |adapter_addresses_number_bytes|.
    auto retval = GetAdaptersAddresses(
        family, GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_DNS_SERVER, nullptr,
        adapter_addresses, &adapter_addresses_number_bytes);

    if (retval == ERROR_SUCCESS) {
      return true;
    }
    if (retval != ERROR_BUFFER_OVERFLOW) {
      // Only retry with more memory if the error says so.
      break;
    }
    SB_LOG(ERROR) << "GetAdapterAddresses() failed with error code " << retval;
  }
  return false;
}

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