/*
 *
 *    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_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
