/*
 *
 *    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/InetError.h>
#include <lib/support/DLLUtil.h>

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

#if CHIP_SYSTEM_CONFIG_USE_BSD_IFADDRS
#include <net/if.h>
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_OPENTHREAD_ENDPOINT
#include <openthread/ip6.h>
#endif // CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT

#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_OPENTHREAD_ENDPOINT && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_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_OPENTHREAD_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_OPENTHREAD_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_OPENTHREAD_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_OPENTHREAD_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_OPENTHREAD_ENDPOINT
    bool mHasCurrent = true;
#endif // CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
};

/**
 * @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_OPENTHREAD_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_OPENTHREAD_ENDPOINT
    const otNetifAddress * mNetifAddrList;
    const otNetifAddress * mCurAddr;
#endif // #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
};

#if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
inline InterfaceIterator::InterfaceIterator(void) {}
inline InterfaceIterator::~InterfaceIterator()               = default;
inline InterfaceAddressIterator::~InterfaceAddressIterator() = default;
inline bool InterfaceIterator::HasCurrent(void)
{
    return mHasCurrent;
}
#endif

#if CHIP_SYSTEM_CONFIG_USE_LWIP && !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_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
