/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2019 Google LLC.
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *
 *    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.
 */

/**
 * @file
 *  This file defines the <tt>Inet::InterfaceId</tt> type alias and related
 *  classes for iterating on the list of system network interfaces and the list
 *  of system interface addresses.
 */

#pragma once

#include <inet/InetConfig.h>

#include <inet/IPAddress.h>
#include <inet/InetError.h>
#include <lib/support/DLLUtil.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
#include <lwip/netif.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
struct if_nameindex;
struct ifaddrs;
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
#include <zephyr/device.h>

struct net_if;
struct net_if_ipv4;
struct net_if_ipv6;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
struct otIp6AddressInfo;
#endif

#include <stddef.h>
#include <stdint.h>

namespace chip {
namespace Inet {

class IPAddress;
class IPPrefix;

/**
 * Data type describing interface type.
 */
enum class InterfaceType
{
    Unknown  = 0,
    WiFi     = 1,
    Ethernet = 2,
    Cellular = 3,
    Thread   = 4,
};

/**
 * Indicator for system network interfaces.
 */
class InterfaceId
{
public:
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    using PlatformType                       = struct netif *;
    static constexpr size_t kMaxIfNameLength = 13; // Names are formatted as %c%c%d
#endif                                             // CHIP_SYSTEM_CONFIG_USE_LWIP

#if (CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK) && CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    using PlatformType                       = unsigned int;
    static constexpr size_t kMaxIfNameLength = IF_NAMESIZE;
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    using PlatformType                       = int;
    static constexpr size_t kMaxIfNameLength = Z_DEVICE_MAX_NAME_LEN;
#endif

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    using PlatformType                       = unsigned int;
    static constexpr size_t kMaxIfNameLength = 6;
#endif

    ~InterfaceId() = default;

    constexpr InterfaceId() : mPlatformInterface(kPlatformNull) {}
    explicit constexpr InterfaceId(PlatformType interface) : mPlatformInterface(interface) {}

    constexpr InterfaceId(const InterfaceId & other) : mPlatformInterface(other.mPlatformInterface) {}
    constexpr InterfaceId & operator=(const InterfaceId & other)
    {
        mPlatformInterface = other.mPlatformInterface;
        return *this;
    }

    static constexpr InterfaceId Null() { return InterfaceId(); }

    constexpr bool operator==(const InterfaceId & other) const { return mPlatformInterface == other.mPlatformInterface; }
    constexpr bool operator!=(const InterfaceId & other) const { return mPlatformInterface != other.mPlatformInterface; }

    /**
     * Test for inequivalence with the null interface.
     */
    bool IsPresent() const { return mPlatformInterface != kPlatformNull; }

    /**
     * Get the underlying platform representation of the interface.
     */
    PlatformType GetPlatformInterface() const { return mPlatformInterface; }

    /**
     * Get the name of the network interface
     *
     * @param[in]   nameBuf     Region of memory to write the interface name.
     * @param[in]   nameBufSize Size of the region denoted by \c nameBuf.
     *
     * @retval  CHIP_NO_ERROR               Successful result, interface name written.
     * @retval  CHIP_ERROR_BUFFER_TOO_SMALL Buffer is too small for the interface name.
     * @retval  other                       Another system or platform error.
     *
     *  Writes the name of the network interface as a \c NUL terminated text string at \c nameBuf.
     *  The name of the unspecified network interface is the empty string.
     */
    CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize) const;

    /**
     * Search the list of network interfaces for the indicated name.
     *
     * @param[in]   intfName    Name of the network interface to find.
     * @param[out]  intfId      Indicator of the network interface to assign.
     *
     * @retval  CHIP_NO_ERROR                   Success, network interface indicated.
     * @retval  INET_ERROR_UNKNOWN_INTERFACE    No network interface found.
     * @retval  other                           Another system or platform error.
     *
     * @note
     *  On LwIP, this function must be called with the LwIP stack lock acquired.
     */
    static CHIP_ERROR InterfaceNameToId(const char * intfName, InterfaceId & intfId);

    /**
     *  Get the interface identifier for the specified IP address. If the
     *  interface identifier cannot be derived it is set to the default InterfaceId.
     *
     *  @note
     *    This function fetches the first interface (from the configured list
     *    of interfaces) that matches the specified IP address.
     */
    static InterfaceId FromIPAddress(const IPAddress & addr);

    /**
     *  Check if there is a prefix match between the specified IPv6 address and any of
     *  the locally configured IPv6 addresses.
     *
     *  @param[in]    addr    The IPv6 address to check for the prefix-match.
     *  @return true if a successful match is found, otherwise false.
     */
    static bool MatchLocalIPv6Subnet(const IPAddress & addr);

    /**
     *  Get the link local IPv6 address.
     *
     *  @param[out]   llAddr  The link local IPv6 address for the link.
     *
     *  @retval    #CHIP_ERROR_NOT_IMPLEMENTED      If IPv6 is not supported.
     *  @retval    #CHIP_ERROR_INVALID_ARGUMENT     If the link local address
     *                                              is nullptr.
     *  @retval    #INET_ERROR_ADDRESS_NOT_FOUND    If the link does not have
     *                                              any address configured
     *                                              or if no link local (fe80::)
     *                                              address is present.
     *  @retval    #CHIP_NO_ERROR                   On success.
     */
    CHIP_ERROR GetLinkLocalAddr(IPAddress * llAddr) const;

private:
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    static constexpr PlatformType kPlatformNull = nullptr;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    static constexpr PlatformType kPlatformNull = 0;
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    static constexpr PlatformType kPlatformNull = 0;
#endif

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    static constexpr PlatformType kPlatformNull = 0;
#endif

    PlatformType mPlatformInterface;
};

/**
 * Compute a prefix length from a variable-length netmask.
 */
extern uint8_t NetmaskToPrefixLength(const uint8_t * netmask, uint16_t netmaskLen);

/**
 * @brief   Iterator for the list of system network interfaces.
 *
 * @details
 *  Use objects of this class to iterate the list of system network interfaces.
 *
 *  Methods on an individual instance of this class are *not* thread-safe;
 *  however separate instances may be used simultaneously by multiple threads.
 *
 *  On multi-threaded LwIP systems, instances are thread-safe relative to other
 *  threads accessing the global LwIP state provided that the other threads hold
 *  the LwIP core lock while mutating the list of netifs, and that netif object
 *  themselves are never destroyed.
 *
 *  On sockets-based systems, iteration is always stable in the face of changes
 *  to the underlying system's interfaces.
 *
 *  On LwIP systems, iteration is stable except in the case where the currently
 *  selected interface is removed from the list, in which case iteration ends
 *  immediately.
 */
class InterfaceIterator
{
public:
    /**
     * Constructs an InterfaceIterator object.
     *
     *  Starts the iterator at the first network interface. On some platforms,
     *  this constructor may allocate resources recycled by the destructor.
     */
    InterfaceIterator();
    ~InterfaceIterator();

    /**
     * Test whether the iterator is positioned on an interface
     *
     * @return  \c true if the iterator is positioned on an interface;
     *          \c false if positioned beyond the end of the interface list.
     */
    bool HasCurrent();

    /**
     * Advance the iterator to the next network interface.
     *
     * @return  \c false if advanced beyond the end, else \c true.
     *
     *  Advances the internal iterator to the next network interface or to a position
     *  beyond the end of the interface list.
     *
     *  On multi-threaded LwIP systems, this method is thread-safe relative to other
     *  threads accessing the global LwIP state provided that: 1) the other threads
     *  hold the LwIP core lock while mutating the list of netifs; and 2) netif objects
     *  themselves are never destroyed.
     *
     *  Iteration is stable in the face of changes to the underlying system's
     *  interfaces, *except* in the case of LwIP systems when the currently selected
     *  interface is removed from the list, which causes iteration to end immediately.
     */
    bool Next();

    /**
     * InterfaceId InterfaceIterator::GetInterfaceId(void)
     *
     * Returns the network interface id at the current iterator position.
     *
     * @retval  id                   The current network interface id.
     * @retval  InterfaceId()   If advanced beyond the end of the list.
     */
    InterfaceId GetInterfaceId();

    /**
     * Get the name of the current network interface
     *
     * @param[in]   nameBuf     Region of memory to write the interface name.
     * @param[in]   nameBufSize Size of the region denoted by \c nameBuf.
     *
     * @retval  CHIP_NO_ERROR               Successful result, interface name written.
     * @retval  CHIP_ERROR_INCORRECT_STATE  Iterator is positioned beyond the end of the list.
     * @retval  CHIP_ERROR_BUFFER_TOO_SMALL Name is too large to be written in buffer.
     * @retval  other                       Another system or platform error.
     *
     *  Writes the name of the network interface as \c NUL terminated text string at \c nameBuf.
     */
    CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);

    /**
     * Returns whether the current network interface is up.
     *
     * @return  \c true if current network interface is up, \c false if not
     *          or if the iterator is positioned beyond the end of the list.
     */
    bool IsUp();

    /**
     * Returns whether the current network interface is a loopback interface
     *
     * @return  \c true if current network interface is a loopback interface, \c false
     *          if not, or if the iterator is positioned beyond the end of the list.
     */
    bool IsLoopback();

    /**
     * Returns whether the current network interface supports multicast.
     *
     * @return  \c true if current network interface supports multicast, \c false
     *          if not, or if the iterator is positioned beyond the end of the list.
     */
    bool SupportsMulticast();

    /**
     * Returns whether the current network interface has a broadcast address.
     *
     * @return  \c true if current network interface has a broadcast address, \c false
     *          if not, or if the iterator is positioned beyond the end of the list.
     */
    bool HasBroadcastAddress();

    /**
     * Get the interface type of the current network interface.
     *
     * @param[out]   type       Object to save the interface type.
     */
    CHIP_ERROR GetInterfaceType(InterfaceType & type);

    /**
     * Get the hardware address of the current network interface
     *
     * @param[out]   addressBuffer       Region of memory to write the hardware address.
     * @param[out]   addressSize         Size of the address saved to a buffer.
     * @param[in]    addressBufferSize   Maximum size of a buffer to save data.
     */
    CHIP_ERROR GetHardwareAddress(uint8_t * addressBuffer, uint8_t & addressSize, uint8_t addressBufferSize);

protected:
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    struct netif * mCurNetif;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    struct if_nameindex * mIntfArray;
    size_t mCurIntf;
    short mIntfFlags;
    bool mIntfFlagsCached;

    short GetFlags();
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    InterfaceId::PlatformType mCurrentId = 1;
    net_if * mCurrentInterface           = nullptr;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    struct otIp6AddressInfo * mCurNetif;
#endif
};

/**
 * @brief   Iterator for the list of system network interface IP addresses.
 *
 * @details
 *  Use objects of this class to iterate the list of system network interface
 *  interface IP addresses.
 *
 *  Methods on an individual instance of this class are *not* thread-safe;
 *  however separate instances may be used simultaneously by multiple threads.
 *
 *  On multi-threaded LwIP systems, instances are thread-safe relative to other
 *  threads accessing the global LwIP state provided that: 1) other threads hold
 *  the LwIP core lock while mutating the list of netifs; and 2) netif object
 *  themselves are never destroyed.
 *
 *  On sockets-based systems, iteration is always stable in the face of changes
 *  to the underlying system's interfaces and/or addresses.
 *
 *  On LwIP systems, iteration is stable except in the case where the interface
 *  associated with the current address is removed, in which case iteration may
 *  end prematurely.
 */
class DLL_EXPORT InterfaceAddressIterator
{
public:
    /**
     * Constructs an InterfaceAddressIterator object.
     *
     *  Starts the iterator at the first network address. On some platforms,
     *  this constructor may allocate resources recycled by the destructor.
     */
    InterfaceAddressIterator();

    /**
     * Destroys an InterfaceAddressIterator object.
     *
     *  Recycles any resources allocated by the constructor.
     */
    ~InterfaceAddressIterator();

    /**
     * Test whether the iterator is positioned on an interface address
     *
     * @return  \c true if the iterator is positioned on an interface address;
     *          \c false if positioned beyond the end of the address list.
     */
    bool HasCurrent();

    /**
     * @fn      bool InterfaceAddressIterator::Next(void)
     *
     * @brief   Advance the iterator to the next interface address.
     *
     * @return  \c false if advanced beyond the end, else \c true.
     *
     * @details
     *     Advances the iterator to the next interface address or to a position
     *     beyond the end of the address list.
     *
     *     On LwIP, this method is thread-safe provided that: 1) other threads hold
     *     the LwIP core lock while mutating the netif list; and 2) netif objects
     *     themselves are never destroyed.  Additionally, iteration on LwIP systems
     *     will terminate early if the current interface is removed from the list.
     */
    bool Next();

    /**
     * @fn      IPAddress InterfaceAddressIterator::GetAddress(void)
     *
     * @brief   Get the current interface address.
     *
     * @param[out] outIPAddress     The current interface address
     *
     * @return CHIP_NO_ERROR        if the result IPAddress is valid.
     * @return CHIP_ERROR_SENTINEL  if the iterator is positioned beyond the end of the address list.
     * @return other error from lower-level code
     */
    CHIP_ERROR GetAddress(IPAddress & outIPAddress);

    /**
     * @fn      uint8_t InterfaceAddressIterator::GetPrefixLength(void)
     *
     * @brief   Gets the network prefix associated with the current interface address.
     *
     * @return  the network prefix (in bits) or 0 if the iterator is positioned beyond
     *          the end of the address list.
     *
     * @details
     *     On LwIP, this method simply returns the hard-coded constant 64.
     *
     *     Note Well: the standard subnet prefix on all links other than PPP
     *     links is 64 bits. On PPP links and some non-broadcast multipoint access
     *     links, the convention is either 127 bits or 128 bits, but it might be
     *     something else. On most platforms, the system's interface address
     *     structure can represent arbitrary prefix lengths between 0 and 128.
     */
    uint8_t GetPrefixLength();

    /**
     * @fn      InterfaceId InterfaceAddressIterator::GetInterfaceId(void)
     *
     * @brief   Returns the network interface id associated with the current
     *          interface address.
     *
     * @return  the interface id or \c InterfaceId() if the iterator
     *          is positioned beyond the end of the address list.
     */
    InterfaceId GetInterfaceId();

    /**
     * @fn      CHIP_ERROR InterfaceAddressIterator::GetInterfaceName(char * nameBuf, size_t nameBufSize)
     *
     * @brief   Get the name of the network interface associated with the
     *          current interface address.
     *
     * @param[in]   nameBuf     region of memory to write the interface name
     * @param[in]   nameBufSize size of the region denoted by \c nameBuf
     *
     * @retval  CHIP_NO_ERROR           successful result, interface name written
     * @retval  CHIP_ERROR_BUFFER_TOO_SMALL    name is too large to be written in buffer
     * @retval  CHIP_ERROR_INCORRECT_STATE
     *                                  the iterator is not currently positioned on an
     *                                  interface address
     * @retval  other                   another system or platform error
     *
     * @details
     *     Writes the name of the network interface as \c NUL terminated text string
     *     at \c nameBuf.
     */
    CHIP_ERROR GetInterfaceName(char * nameBuf, size_t nameBufSize);

    /**
     * Returns whether the network interface associated with the current interface address is up.
     *
     * @return  \c true if current network interface is up, \c false if not, or
     *          if the iterator is not positioned on an interface address.
     */
    bool IsUp();

    /**
     * Returns whether the current network interface is a loopback interface
     *
     * @return  \c true if current network interface is a loopback interface, \c false
     *          if not, or if the iterator is positioned beyond the end of the list.
     */
    bool IsLoopback();

    /**
     * Returns whether the network interface associated with the current interface address supports multicast.
     *
     * @return  \c true if multicast is supported, \c false if not, or
     *          if the iterator is not positioned on an interface address.
     */
    bool SupportsMulticast();

    /**
     * Returns whether the network interface associated with the current interface address has an IPv4 broadcast address.
     *
     * @return  \c true if the interface has a broadcast address, \c false if not, or
     *          if the iterator is not positioned on an interface address.
     */
    bool HasBroadcastAddress();

private:
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    enum
    {
        kBeforeStartIndex = -1
    };

    InterfaceIterator mIntfIter;
    int mCurAddrIndex;
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
    struct ifaddrs * mAddrsList;
    struct ifaddrs * mCurAddr;
#endif // CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
    InterfaceIterator mIntfIter;
    net_if_ipv6 * mIpv6 = nullptr;
    int mCurAddrIndex   = -1;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
    const otNetifAddress * mNetifAddrList;
    const otNetifAddress * mCurAddr;
#endif // #if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
};

#if CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT
inline InterfaceIterator::InterfaceIterator(void) {}
inline InterfaceIterator::~InterfaceIterator()               = default;
inline InterfaceAddressIterator::~InterfaceAddressIterator() = default;
inline bool InterfaceIterator::HasCurrent(void)
{
    return mCurNetif != NULL;
}
#endif

#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT

inline InterfaceIterator::InterfaceIterator(void)
{
    mCurNetif = netif_list;
}

inline InterfaceIterator::~InterfaceIterator(void) {}

inline bool InterfaceIterator::HasCurrent(void)
{
    return mCurNetif != NULL;
}

inline InterfaceId InterfaceIterator::GetInterfaceId(void)
{
    return InterfaceId(mCurNetif);
}

inline InterfaceAddressIterator::InterfaceAddressIterator(void)
{
    mCurAddrIndex = kBeforeStartIndex;
}

inline InterfaceAddressIterator::~InterfaceAddressIterator(void) {}

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF
inline InterfaceIterator::~InterfaceIterator()               = default;
inline InterfaceAddressIterator::~InterfaceAddressIterator() = default;
#endif // CHIP_SYSTEM_CONFIG_USE_ZEPHYR_NET_IF

} // namespace Inet
} // namespace chip
