/*
 *  Copyright (c) 2018, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef ROUTER_TABLE_HPP_
#define ROUTER_TABLE_HPP_

#include "common/encoding.hpp"
#include "common/locator.hpp"
#include "mac/mac_types.hpp"
#include "thread/mle_constants.hpp"
#include "thread/thread_tlvs.hpp"
#include "thread/topology.hpp"

namespace ot {

#if OPENTHREAD_FTD

class RouterTable : public InstanceLocator
{
public:
    /**
     * This class represents an iterator for iterating through entries in the router table.
     *
     */
    class Iterator : public InstanceLocator
    {
    public:
        /**
         * This constructor initializes an `Iterator` instance to start from beginning of the router table.
         *
         * @param[in] aInstance  A reference to the OpenThread instance.
         *
         */
        explicit Iterator(Instance &aInstance);

        /**
         * This method resets the iterator to start over.
         *
         */
        void Reset(void);

        /**
         * This method indicates if the iterator has reached the end of the list.
         *
         * @retval TRUE   The iterator has reached the end of the list.
         * @retval FALSE  The iterator currently points to a valid entry.
         *
         */
        bool IsDone(void) const { return (mRouter == NULL); }

        /**
         * This method advances the iterator.
         *
         * The iterator is moved to point to the next entry.  If there are no more entries matching the iterator
         * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`).
         *
         */
        void Advance(void);

        /**
         * This method overloads `++` operator (pre-increment) to advance the iterator.
         *
         * The iterator is moved to point to the next entry.  If there are no more entries matching the iterator
         * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`).
         *
         */
        void operator++(void) { Advance(); }

        /**
         * This method overloads `++` operator (post-increment) to advance the iterator.
         *
         * The iterator is moved to point to the next entry.  If there are no more entries matching the iterator
         * becomes empty (i.e., `GetRouter()` returns `NULL` and `IsDone()` returns `true`).
         *
         */
        void operator++(int) { Advance(); }

        /**
         * This method gets the entry to which the iterator is currently pointing.
         *
         * @returns A pointer to the current entry, or `NULL` if the iterator is done/empty.
         *
         */
        Router *GetRouter(void) { return mRouter; }

    private:
        Router *mRouter;
    };

    /**
     * Constructor.
     *
     * @param[in]  aInstance  A reference to the OpenThread instance.
     *
     */
    explicit RouterTable(Instance &aInstance);

    /**
     * This method clears the router table.
     *
     */
    void Clear(void);

    /**
     * This method removes all neighbor links to routers.
     *
     */
    void ClearNeighbors(void);

    /**
     * This method allocates a router with a random router id.
     *
     * @returns A pointer to the allocated router or NULL if a router ID is not available.
     *
     */
    Router *Allocate(void);

    /**
     * This method allocates a router with a specified router id.
     *
     * @returns A pointer to the allocated router or NULL if the router id could not be allocated.
     *
     */
    Router *Allocate(uint8_t aRouterId);

    /**
     * This method releases a router id.
     *
     * @param[in]  aRouterId  The router id.
     *
     * @retval OT_ERROR_NONE           Successfully released the router id.
     * @retval OT_ERROR_INVALID_STATE  The device is not currently operating as a leader.
     * @retval OT_ERROR_NOT_FOUND      The router id is not currently allocated.
     *
     */
    otError Release(uint8_t aRouterId);

    /**
     * This method removes a neighboring router link.
     *
     * @param[in]  aRouter  A reference to the router.
     *
     */
    void RemoveNeighbor(Router &aRouter);

    /**
     * This method returns the number of active routers in the Thread network.
     *
     * @returns The number of active routers in the Thread network.
     *
     */
    uint8_t GetActiveRouterCount(void) const { return mActiveRouterCount; }

    /**
     * This method returns the number of active links with neighboring routers.
     *
     * @returns The number of active links with neighboring routers.
     *
     */
    uint8_t GetActiveLinkCount(void) const;

    /**
     * This method returns the leader in the Thread network.
     *
     * @returns A pointer to the Leader in the Thread network.
     *
     */
    Router *GetLeader(void);

    /**
     * This method returns the time in seconds since the last Router ID Sequence update.
     *
     * @returns The time in seconds since the last Router ID Sequence update.
     *
     */
    uint32_t GetLeaderAge(void) const;

    /**
     * This method returns the link cost for a neighboring router.
     *
     * @param[in]  aRouter  A reference to the router.
     *
     * @returns The link cost.
     *
     */
    uint8_t GetLinkCost(Router &aRouter);

    /**
     * This method returns the neighbor for a given RLOC16.
     *
     * @param[in]  aRloc16  The RLOC16 value.
     *
     * @returns A pointer to the router or NULL if the router could not be found.
     *
     */
    Router *GetNeighbor(uint16_t aRloc16);

    /**
     * This method returns the neighbor for a given IEEE Extended Address.
     *
     * @param[in]  aExtAddress  A reference to the IEEE Extended Address.
     *
     * @returns A pointer to the router or NULL if the router could not be found.
     *
     */
    Router *GetNeighbor(const Mac::ExtAddress &aExtAddress);

    /**
     * This method returns the router for a given router id.
     *
     * @param[in]  aRouterId  The router id.
     *
     * @returns A pointer to the router or NULL if the router could not be found.
     *
     */
    Router *GetRouter(uint8_t aRouterId)
    {
        return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetRouter(aRouterId));
    }

    /**
     * This method returns the router for a given router id.
     *
     * @param[in]  aRouterId  The router id.
     *
     * @returns A pointer to the router or NULL if the router could not be found.
     *
     */
    const Router *GetRouter(uint8_t aRouterId) const;

    /**
     * This method returns the router for a given IEEE Extended Address.
     *
     * @param[in]  aExtAddress  A reference to the IEEE Extended Address.
     *
     * @returns A pointer to the router or NULL if the router could not be found.
     *
     */
    Router *GetRouter(const Mac::ExtAddress &aExtAddress);

    /**
     * This method retains diagnostic information for a given router.
     *
     * @param[in]   aRouterId    The router ID or RLOC16 for a given router.
     * @param[out]  aRouterInfo  The router information.
     *
     * @retval OT_ERROR_NONE          Successfully retrieved the router info for given id.
     * @retval OT_ERROR_INVALID_ARGS  @p aRouterId is not a valid value for a router.
     * @retval OT_ERROR_NOT_FOUND     No router entry with the given id.
     *
     */
    otError GetRouterInfo(uint16_t aRouterId, otRouterInfo &aRouterInfo);

    /**
     * This method returns the Router ID Sequence.
     *
     * @returns The Router ID Sequence.
     *
     */
    uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }

    /**
     * This method returns the local time when the Router ID Sequence was last updated.
     *
     * @returns The local time when the Router ID Sequence was last updated.
     *
     */
    TimeMilli GetRouterIdSequenceLastUpdated(void) const { return mRouterIdSequenceLastUpdated; }

    /**
     * This method returns the number of neighbor links.
     *
     * @returns The number of neighbor links.
     *
     */
    uint8_t GetNeighborCount(void) const;

    /**
     * This method indicates whether or not @p aRouterId is allocated.
     *
     * @retval TRUE if @p aRouterId is allocated.
     * @retval FALSE if @p aRouterId is not allocated.
     *
     */
    bool IsAllocated(uint8_t aRouterId) const;

    /**
     * This method updates the router table with a received Route TLV.
     *
     * @param[in]  aTlv  A reference to the Route TLV.
     *
     */
    void ProcessTlv(const Mle::RouteTlv &aTlv);

    /**
     * This method updates the router table with a received Router Mask TLV.
     *
     * @param[in]  aTlv  A reference to the Router Mask TLV.
     *
     */
    void ProcessTlv(const ThreadRouterMaskTlv &aTlv);

    /**
     * This method updates the router table and must be called with a one second period.
     *
     */
    void ProcessTimerTick(void);

private:
    class RouterIdSet
    {
    public:
        void Clear(void) { memset(mRouterIdSet, 0, sizeof(mRouterIdSet)); }
        bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & (1 << (aRouterId % 8))) != 0; }
        void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= 1 << (aRouterId % 8); }
        void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~(1 << (aRouterId % 8)); }

    private:
        uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
    };

    void          UpdateAllocation(void);
    const Router *GetFirstEntry(void) const;
    const Router *GetNextEntry(const Router *aRouter) const;
    Router *GetFirstEntry(void) { return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetFirstEntry()); }
    Router *GetNextEntry(Router *aRouter)
    {
        return const_cast<Router *>(const_cast<const RouterTable *>(this)->GetNextEntry(aRouter));
    }

    Router      mRouters[Mle::kMaxRouters];
    RouterIdSet mAllocatedRouterIds;
    uint8_t     mRouterIdReuseDelay[Mle::kMaxRouterId + 1];
    TimeMilli   mRouterIdSequenceLastUpdated;
    uint8_t     mRouterIdSequence;
    uint8_t     mActiveRouterCount;
};

#endif // OPENTHREAD_FTD

#if OPENTHREAD_MTD

class RouterTable
{
public:
    class Iterator
    {
    public:
        explicit Iterator(Instance &) {}
        void    Reset(void) {}
        bool    IsDone(void) const { return true; }
        void    Advance(void) {}
        void    operator++(void) {}
        void    operator++(int) {}
        Router *GetRouter(void) { return NULL; }
    };

    explicit RouterTable(Instance &) {}

    uint8_t GetNeighborCount(void) const { return 0; }
};

#endif // OPENTHREAD_MTD

} // namespace ot

#endif // ROUTER_TABLE_HPP_
