// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "platform/impl/network_interface.h"

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>

#include "util/osp_logging.h"

namespace openscreen {

std::vector<InterfaceInfo> GetAllInterfaces() {
    constexpr size_t INITIAL_BUFFER_SIZE = 15000;
    ULONG outbuflen = INITIAL_BUFFER_SIZE;
    std::vector<unsigned char> charbuf(INITIAL_BUFFER_SIZE);
    PIP_ADAPTER_ADDRESSES paddrs = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(charbuf.data());
    DWORD ret = NO_ERROR;
    constexpr int MAX_RETRIES = 5;

    for (int i = 0; i < MAX_RETRIES; ++i) {
        // TODO: This does not include the loopback interface. Decide if we need it.
        ret = GetAdaptersAddresses(AF_UNSPEC /* get both v4/v6 addrs */,
                                   GAA_FLAG_INCLUDE_PREFIX,
                                   NULL,
                                   paddrs,
                                   &outbuflen);
        if (ret == ERROR_BUFFER_OVERFLOW) {
            charbuf.resize(outbuflen);
            continue;
        }
        break;
    }

    if (ret != NO_ERROR) {
        OSP_DVLOG << "GetAdapterAddresses failed err=" << ret;
        return std::vector<InterfaceInfo>();
    }

    std::vector<InterfaceInfo> infos;
    auto pcurraddrs = paddrs;
    while (pcurraddrs != nullptr) {
        // TODO: return the interfaces
        OSP_DVLOG << "\tIfIndex=" << pcurraddrs->IfIndex;
        OSP_DVLOG << "\tAdapter name=" << pcurraddrs->AdapterName;

        // Ignore interfaces that are down
        if (pcurraddrs->OperStatus == IfOperStatusDown) {
            pcurraddrs = pcurraddrs->Next;
            continue;
        }

        infos.emplace_back();
        InterfaceInfo& info = infos.back();

        info.index = pcurraddrs->IfIndex;
        std::memcpy(info.hardware_address.data(), pcurraddrs->PhysicalAddress,
                std::min((unsigned long)sizeof(info.hardware_address),
                    pcurraddrs->PhysicalAddressLength));
        info.name = pcurraddrs->AdapterName;

        // Determine the interface type
        switch (pcurraddrs->IfType) {
            case IF_TYPE_ETHERNET_CSMACD:
                info.type = InterfaceInfo::Type::kEthernet;
                break;
            case IF_TYPE_IEEE80211:
                info.type = InterfaceInfo::Type::kWifi;
                break;
            case IF_TYPE_SOFTWARE_LOOPBACK:
                info.type = InterfaceInfo::Type::kLoopback;
                break;
            default:
                info.type = InterfaceInfo::Type::kOther;
                break;
        }

        auto punicast = pcurraddrs->FirstUnicastAddress;
        if (punicast != nullptr) {
            for (int i = 0; punicast != nullptr; ++i) {
                if (punicast->Address.lpSockaddr->sa_family == AF_INET) {
                    sockaddr_in* sa_in = (sockaddr_in*)punicast->Address.lpSockaddr;
                    char buff[100];
                    DWORD bufflen = 100;
                    OSP_DVLOG << "\tIPV4:" << inet_ntop(AF_INET, &(sa_in->sin_addr), buff, bufflen);
                    OSP_DVLOG << "\t  prefixsize=" << (unsigned int)punicast->OnLinkPrefixLength;
                    IPAddress ip(IPAddress::Version::kV4,
                            reinterpret_cast<uint8_t*>(&(sa_in->sin_addr.s_addr)));
                    info.addresses.emplace_back(ip, punicast->OnLinkPrefixLength);
                } else if (punicast->Address.lpSockaddr->sa_family == AF_INET6) {
                    sockaddr_in6* sa_in6 = (sockaddr_in6*)punicast->Address.lpSockaddr;
                    char buff[100];
                    DWORD bufflen = 100;
                    OSP_DVLOG << "\tIPV6:" << inet_ntop(AF_INET6, &(sa_in6->sin6_addr), buff, bufflen);
                    OSP_DVLOG << "\t  prefixsize=" << (unsigned int)punicast->OnLinkPrefixLength;
                    IPAddress ip(IPAddress::Version::kV6,
                            reinterpret_cast<uint8_t*>(&(sa_in6->sin6_addr.s6_addr)));
                    info.addresses.emplace_back(ip, punicast->OnLinkPrefixLength);
                } else {
                    OSP_DVLOG << "\tUNSPEC";
                }
                punicast = punicast->Next;
            }
        }
        OSP_DVLOG << "\tIfType=" << pcurraddrs->IfType;
        OSP_DVLOG << "\tDescription=" << pcurraddrs->Description;
        OSP_DVLOG << "\tFreindlyName=" << pcurraddrs->FriendlyName;
        pcurraddrs = pcurraddrs->Next;
    }
    return infos;
}

}  // namespace openscreen
