#pragma once
#include <fmt/core.h>
#include <net/ethernet.h>
#include <netinet/in.h>

#include <algorithm>
#include <array>
#include <numeric>
#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <variant>

constexpr bool operator==(ether_addr lhs, ether_addr rhs) noexcept
{
    return std::equal(lhs.ether_addr_octet, lhs.ether_addr_octet + 6,
                      rhs.ether_addr_octet);
}

constexpr bool operator==(in_addr lhs, in_addr rhs) noexcept
{
    return lhs.s_addr == rhs.s_addr;
}

constexpr bool operator==(in6_addr lhs, in6_addr rhs) noexcept
{
    return std::equal(lhs.s6_addr32, lhs.s6_addr32 + 4, rhs.s6_addr32);
}

namespace phosphor
{
namespace network
{

// Byte representations for common address types in network byte order
using InAddrAny = std::variant<in_addr, in6_addr>;
class IfAddr
{
  private:
    InAddrAny addr;
    uint8_t pfx;

    static void invalidPfx(uint8_t pfx);

  public:
    constexpr IfAddr() : addr({}), pfx(0)
    {
    }

    constexpr IfAddr(InAddrAny addr, uint8_t pfx) : addr(addr), pfx(pfx)
    {
        std::visit(
            [pfx](auto v) {
                if (sizeof(v) * 8 < pfx)
                {
                    invalidPfx(pfx);
                }
            },
            addr);
    }

    constexpr auto getAddr() const
    {
        return addr;
    }

    constexpr auto getPfx() const
    {
        return pfx;
    }

    constexpr bool operator==(phosphor::network::IfAddr rhs) const noexcept
    {
        return addr == rhs.addr && pfx == rhs.pfx;
    }
};

/** @class InterfaceInfo
 *  @brief Information about interfaces from the kernel
 */
struct InterfaceInfo
{
    unsigned idx;
    unsigned flags;
    std::optional<std::string> name = std::nullopt;
    std::optional<ether_addr> mac = std::nullopt;
    std::optional<unsigned> mtu = std::nullopt;
    std::optional<unsigned> parent_idx = std::nullopt;
    std::optional<std::string> kind = std::nullopt;
    std::optional<uint16_t> vlan_id = std::nullopt;

    constexpr bool operator==(const InterfaceInfo& rhs) const noexcept
    {
        return idx == rhs.idx && flags == rhs.flags && name == rhs.name &&
               mac == rhs.mac && mtu == rhs.mtu &&
               parent_idx == rhs.parent_idx && kind == rhs.kind &&
               vlan_id == rhs.vlan_id;
    }
};

/** @class AddressInfo
 *  @brief Information about a addresses from the kernel
 */
struct AddressInfo
{
    unsigned ifidx;
    IfAddr ifaddr;
    uint8_t scope;
    uint32_t flags;

    constexpr bool operator==(const AddressInfo& rhs) const noexcept
    {
        return ifidx == rhs.ifidx && ifaddr == rhs.ifaddr &&
               scope == rhs.scope && flags == rhs.flags;
    }
};

/** @class NeighborInfo
 *  @brief Information about a neighbor from the kernel
 */
struct NeighborInfo
{
    unsigned ifidx;
    uint16_t state;
    std::optional<InAddrAny> addr;
    std::optional<ether_addr> mac;

    constexpr bool operator==(const NeighborInfo& rhs) const noexcept
    {
        return ifidx == rhs.ifidx && state == rhs.state && addr == rhs.addr &&
               mac == rhs.mac;
    }
};

struct string_hash : public std::hash<std::string_view>
{
    using is_transparent = void;
};
template <typename V>
using string_umap =
    std::unordered_map<std::string, V, string_hash, std::equal_to<>>;
using string_uset =
    std::unordered_set<std::string, string_hash, std::equal_to<>>;

constexpr std::size_t hash_multi() noexcept
{
    return 0;
}

template <typename T, typename... Args>
constexpr std::size_t hash_multi(const T& v, const Args&... args) noexcept
{
    const std::size_t seed = hash_multi(args...);
    return seed ^ (std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}

namespace detail
{

template <typename T, uint8_t size = sizeof(T)>
struct BswapAlign
{
    using type = T;
};

template <typename T>
struct BswapAlign<T, 2>
{
    using type alignas(uint16_t) = T;
};

template <typename T>
struct BswapAlign<T, 4>
{
    using type alignas(uint32_t) = T;
};

template <typename T>
struct BswapAlign<T, 8>
{
    using type alignas(uint64_t) = T;
};

template <typename T>
constexpr T bswapInt(typename BswapAlign<T>::type n) noexcept
{
    static_assert(std::is_trivially_copyable_v<T>);
    if constexpr (sizeof(T) == 2)
    {
        reinterpret_cast<uint16_t&>(n) =
            __builtin_bswap16(reinterpret_cast<uint16_t&>(n));
    }
    else if constexpr (sizeof(T) == 4)
    {
        reinterpret_cast<uint32_t&>(n) =
            __builtin_bswap32(reinterpret_cast<uint32_t&>(n));
    }
    else if constexpr (sizeof(T) == 8)
    {
        reinterpret_cast<uint64_t&>(n) =
            __builtin_bswap64(reinterpret_cast<uint64_t&>(n));
    }
    else
    {
        auto b = reinterpret_cast<std::byte*>(&n);
        std::reverse(b, b + sizeof(n));
    }
    return n;
}

} // namespace detail

template <typename T>
constexpr T bswap(T n) noexcept
{
    return detail::bswapInt<T>(n);
}

template <typename T>
constexpr T hton(T n) noexcept
{
    if constexpr (std::endian::native == std::endian::big)
    {
        return n;
    }
    else if constexpr (std::endian::native == std::endian::little)
    {
        return bswap(n);
    }
    else
    {
        static_assert(std::is_same_v<T, void>);
    }
}

template <typename T>
constexpr T ntoh(T n) noexcept
{
    return hton(n);
}

namespace detail
{
inline constexpr auto charLookup = []() {
    std::array<int8_t, 256> ret;
    std::fill(ret.begin(), ret.end(), -1);
    for (int8_t i = 0; i < 10; ++i)
    {
        ret[i + '0'] = i;
    }
    for (int8_t i = 0; i < 26; ++i)
    {
        ret[i + 'A'] = i + 10;
        ret[i + 'a'] = i + 10;
    }
    return ret;
}();
inline constexpr auto intLookup = []() {
    std::array<char, 36> ret;
    for (int8_t i = 0; i < 10; ++i)
    {
        ret[i] = i + '0';
    }
    for (int8_t i = 0; i < 26; ++i)
    {
        ret[i + 10] = i + 'a';
    }
    return ret;
}();
} // namespace detail

template <typename T, uint8_t base>
struct DecodeInt
{
    static_assert(base > 1 && base <= 36);
    static_assert(std::is_unsigned_v<T>);

    constexpr T operator()(std::string_view str) const
    {
        if (str.empty())
        {
            throw std::invalid_argument("Empty Str");
        }
        constexpr auto max = std::numeric_limits<T>::max();
        auto ret =
            std::accumulate(str.begin(), str.end(), T{}, [&](T r, char c) {
                auto v = detail::charLookup[c];
                if (v < 0 || v >= base)
                {
                    throw std::invalid_argument("Invalid numeral");
                }
                if constexpr (std::popcount(base) == 1)
                {
                    constexpr auto shift = std::countr_zero(base);
                    constexpr auto maxshift = max >> shift;
                    if (r > maxshift)
                    {
                        throw std::overflow_error("Integer Decode");
                    }
                    return (r << shift) | v;
                }
                else
                {
                    constexpr auto maxbase = max / base;
                    if (r > maxbase)
                    {
                        throw std::overflow_error("Integer Decode");
                    }
                    r *= base;
                    if (max - v < r)
                    {
                        throw std::overflow_error("Integer Decode");
                    }
                    return r + v;
                }
            });
        return ret;
    }
};

template <typename T, uint8_t base>
struct EncodeInt
{
    static_assert(base > 1 && base <= 36);
    static_assert(std::is_unsigned_v<T>);

    static constexpr uint8_t buf_size = []() {
        T v = std::numeric_limits<T>::max();
        uint8_t i = 0;
        for (; v != 0; ++i)
        {
            v /= base;
        }
        return i;
    }();
    using buf_type = std::array<char, buf_size>;

    constexpr uint8_t reverseFill(char* buf, T v) const noexcept
    {
        uint8_t i = 0;
        do
        {
            if constexpr (std::popcount(base) == 1)
            {
                buf[i++] = detail::intLookup[v & 0xf];
                v >>= 4;
            }
            else
            {
                buf[i++] = detail::intLookup[v % base];
                v /= base;
            }
        } while (v > 0);
        return i;
    }

    constexpr char* operator()(char* buf, T v) const noexcept
    {
        uint8_t i = reverseFill(buf, v);
        std::reverse(buf, buf + i);
        return buf + i;
    }

    constexpr char* operator()(char* buf, T v, uint8_t min_width) const noexcept
    {
        uint8_t i = reverseFill(buf, v);
        auto end = buf + std::max(i, min_width);
        std::fill(buf + i, end, '0');
        std::reverse(buf, end);
        return end;
    }
};

template <typename T>
struct ToAddr
{
};

template <>
struct ToAddr<ether_addr>
{
    constexpr ether_addr operator()(std::string_view str) const
    {
        constexpr DecodeInt<uint8_t, 16> di;
        ether_addr ret;
        if (str.size() == 12 && str.find(":") == str.npos)
        {
            for (size_t i = 0; i < 6; ++i)
            {
                ret.ether_addr_octet[i] = di(str.substr(i * 2, 2));
            }
        }
        else
        {
            for (size_t i = 0; i < 5; ++i)
            {
                auto loc = str.find(":");
                ret.ether_addr_octet[i] = di(str.substr(0, loc));
                str.remove_prefix(loc == str.npos ? str.size() : loc + 1);
                if (str.empty())
                {
                    throw std::invalid_argument("Missing mac data");
                }
            }
            ret.ether_addr_octet[5] = di(str);
        }
        return ret;
    }
};

template <>
struct ToAddr<in_addr>
{
    constexpr in_addr operator()(std::string_view str) const
    {
        constexpr DecodeInt<uint8_t, 10> di;
        uint32_t addr = {};
        for (size_t i = 0; i < 3; ++i)
        {
            auto loc = str.find(".");
            addr |= di(str.substr(0, loc));
            addr <<= 8;
            str.remove_prefix(loc == str.npos ? str.size() : loc + 1);
            if (str.empty())
            {
                throw std::invalid_argument("Missing addr data");
            }
        }
        addr |= di(str);
        return {hton(addr)};
    }
};

template <>
struct ToAddr<in6_addr>
{
    constexpr in6_addr operator()(std::string_view str) const
    {
        constexpr DecodeInt<uint16_t, 16> di;
        in6_addr ret = {};
        size_t i = 0;
        while (i < 8)
        {
            auto loc = str.find(':');
            if (i == 6 && loc == str.npos)
            {
                ret.s6_addr32[3] = ToAddr<in_addr>{}(str).s_addr;
                return ret;
            }
            if (loc != 0 && !str.empty())
            {
                ret.s6_addr16[i++] = hton(di(str.substr(0, loc)));
            }
            if (i < 8 && str.size() > loc + 1 && str[loc + 1] == ':')
            {
                str.remove_prefix(loc + 2);
                break;
            }
            else if (str.empty())
            {
                throw std::invalid_argument("IPv6 Data");
            }
            str.remove_prefix(loc == str.npos ? str.size() : loc + 1);
        }
        if (str.starts_with(':'))
        {
            throw std::invalid_argument("Extra separator");
        }
        size_t j = 7;
        if (!str.empty() && i < 6 && str.find('.') != str.npos)
        {
            auto loc = str.rfind(':');
            ret.s6_addr32[3] =
                ToAddr<in_addr>{}(str.substr(loc == str.npos ? 0 : loc + 1))
                    .s_addr;
            str.remove_suffix(loc == str.npos ? str.size() : str.size() - loc);
            j -= 2;
        }
        while (!str.empty() && j > i)
        {
            auto loc = str.rfind(':');
            ret.s6_addr16[j--] =
                hton(di(str.substr(loc == str.npos ? 0 : loc + 1)));
            str.remove_suffix(loc == str.npos ? str.size() : str.size() - loc);
        }
        if (!str.empty())
        {
            throw std::invalid_argument("Too much data");
        }
        return ret;
    }
};

template <>
struct ToAddr<InAddrAny>
{
    constexpr InAddrAny operator()(std::string_view str) const
    {
        if (str.find(':') == str.npos)
        {
            return ToAddr<in_addr>{}(str);
        }
        return ToAddr<in6_addr>{}(str);
    }
};

template <>
struct ToAddr<IfAddr>
{
    constexpr IfAddr operator()(std::string_view str) const
    {
        auto pos = str.rfind('/');
        if (pos == str.npos)
        {
            throw std::invalid_argument("Invalid IfAddr");
        }
        return {ToAddr<InAddrAny>{}(str.substr(0, pos)),
                DecodeInt<uint8_t, 10>{}(str.substr(pos + 1))};
    }
};

template <typename T>
struct ToStr
{
};

template <>
struct ToStr<char>
{
    static constexpr uint8_t buf_size = 1;
    using buf_type = std::array<char, buf_size>;

    constexpr char* operator()(char* buf, char v) const noexcept
    {
        buf[0] = v;
        return buf + 1;
    }
};

template <>
struct ToStr<ether_addr>
{
    // 6 octets * 2 hex chars + 5 separators
    static constexpr uint8_t buf_size = 17;
    using buf_type = std::array<char, buf_size>;

    constexpr char* operator()(char* buf, ether_addr v) const noexcept
    {
        for (char* ptr = buf + 2; ptr < buf + buf_size; ptr += 3)
        {
            *ptr = ':';
        }
        for (size_t i = 0; i < 6; ++i)
        {
            char* tmp = buf + i * 3;
            uint8_t byte = v.ether_addr_octet[i];
            EncodeInt<uint8_t, 16>{}(tmp, byte, 2);
        }
        return buf + buf_size;
    }
};

template <>
struct ToStr<in_addr>
{
    // 4 octets * 3 dec chars + 3 separators
    static constexpr uint8_t buf_size = 15;
    using buf_type = std::array<char, buf_size>;

    constexpr char* operator()(char* buf, in_addr v) const noexcept
    {
        auto n = bswap(ntoh(v.s_addr));
        for (size_t i = 0; i < 3; ++i)
        {
            buf = ToStr<char>{}(EncodeInt<uint8_t, 10>{}(buf, n & 0xff), '.');
            n >>= 8;
        }
        return EncodeInt<uint8_t, 10>{}(buf, n & 0xff);
    }
};

template <>
struct ToStr<in6_addr>
{
    // 8 hextets * 4 hex chars + 7 separators
    static constexpr uint8_t buf_size = 39;
    using buf_type = std::array<char, buf_size>;

    constexpr char* operator()(char* buf, in6_addr v) const noexcept
    {
        // IPv4 in IPv6 Addr
        if (v.s6_addr32[0] == 0 && v.s6_addr32[1] == 0 &&
            v.s6_addr32[2] == hton(uint32_t(0xffff)))
        {
            constexpr auto prefix = std::string_view("::ffff:");
            return ToStr<in_addr>{}(
                std::copy(prefix.begin(), prefix.end(), buf), {v.s6_addr32[3]});
        }

        size_t skip_start = 0;
        size_t skip_size = 0;
        {
            size_t new_start = 0;
            size_t new_size = 0;
            for (size_t i = 0; i < 9; ++i)
            {
                if (i < 8 && v.s6_addr16[i] == 0)
                {
                    if (new_start + new_size == i)
                    {
                        new_size++;
                    }
                    else
                    {
                        new_start = i;
                        new_size = 1;
                    }
                }
                else if (new_start + new_size == i && new_size > skip_size)
                {
                    skip_start = new_start;
                    skip_size = new_size;
                }
            }
        }
        for (size_t i = 0; i < 8; ++i)
        {
            if (i == skip_start && skip_size > 1)
            {
                if (i == 0)
                {
                    *(buf++) = ':';
                }
                *(buf++) = ':';
                i += skip_size - 1;
                continue;
            }
            buf = EncodeInt<uint16_t, 16>{}(buf, ntoh(v.s6_addr16[i]));
            if (i < 7)
            {
                *(buf++) = ':';
            }
        }
        return buf;
    }
};

template <>
struct ToStr<InAddrAny>
{
    // IPv6 is the bigger of the addrs
    static constexpr uint8_t buf_size = ToStr<in6_addr>::buf_size;
    using buf_type = std::array<char, buf_size>;

    constexpr char* operator()(char* buf, InAddrAny v) const noexcept
    {
        return std::visit([=](auto v) { return ToStr<decltype(v)>{}(buf, v); },
                          v);
    }
};

template <>
struct ToStr<IfAddr>
{
    // InAddrAny + sep + 3 prefix chars
    static constexpr uint8_t buf_size = ToStr<InAddrAny>::buf_size + 4;
    using buf_type = std::array<char, buf_size>;

    constexpr char* operator()(char* buf, IfAddr v) const noexcept
    {
        buf = ToStr<InAddrAny>{}(buf, v.getAddr());
        buf = ToStr<char>{}(buf, '/');
        return EncodeInt<uint8_t, 10>{}(buf, v.getPfx());
    }
};

namespace detail
{

template <typename T>
constexpr bool vcontains() noexcept
{
    return false;
}

template <typename T, typename V, typename... Vs>
constexpr bool vcontains() noexcept
{
    return vcontains<T, Vs...>() || std::is_same_v<T, V>;
}

template <typename T, typename... Types>
constexpr std::enable_if_t<vcontains<T, Types...>(), bool>
    veq(T t, std::variant<Types...> v) noexcept
{
    return std::visit(
        [t](auto v) {
            if constexpr (std::is_same_v<T, decltype(v)>)
            {
                return v == t;
            }
            else
            {
                return false;
            }
        },
        v);
}

template <typename T>
struct ToStrBuf
{
  public:
    constexpr std::string_view operator()(T v) noexcept
    {
        return {buf.data(), ToStr<T>{}(buf.data(), v)};
    }

  private:
    typename ToStr<T>::buf_type buf;
};

template <typename T>
struct Format
{
  private:
    fmt::formatter<std::string_view> formatter;

  public:
    template <typename ParseContext>
    constexpr auto parse(ParseContext& ctx)
    {
        return ctx.begin();
    }

    template <typename FormatContext>
    auto format(auto v, FormatContext& ctx) const
    {
        return formatter.format(ToStrBuf<T>{}(v), ctx);
    }
};
} // namespace detail
} // namespace network
} // namespace phosphor

template <typename... Ts>
struct std::hash<std::tuple<Ts...>>
{
    constexpr auto operator()(const std::tuple<Ts...>& t) const noexcept
    {
        return std::apply(phosphor::network::hash_multi<Ts...>, t);
    }
};

template <>
struct std::hash<in_addr>
{
    std::size_t operator()(in_addr addr) const noexcept;
};

template <>
struct std::hash<in6_addr>
{
    std::size_t operator()(in6_addr addr) const noexcept;
};

template <>
struct std::hash<phosphor::network::IfAddr>
{
    std::size_t operator()(phosphor::network::IfAddr addr) const noexcept;
};

namespace fmt
{
template <>
struct formatter<ether_addr> : phosphor::network::detail::Format<ether_addr>
{
};
template <>
struct formatter<in_addr> : phosphor::network::detail::Format<in_addr>
{
};
template <>
struct formatter<in6_addr> : phosphor::network::detail::Format<in6_addr>
{
};
template <>
struct formatter<phosphor::network::InAddrAny>
    : phosphor::network::detail::Format<phosphor::network::InAddrAny>
{
};
template <>
struct formatter<phosphor::network::IfAddr>
    : phosphor::network::detail::Format<phosphor::network::IfAddr>
{
};
} // namespace fmt

namespace std
{
string to_string(ether_addr value);
string to_string(in_addr value);
string to_string(in6_addr value);
string to_string(phosphor::network::InAddrAny value);
string to_string(phosphor::network::IfAddr value);
} // namespace std

template <typename T>
constexpr std::enable_if_t<!std::is_same_v<phosphor::network::InAddrAny, T>,
                           bool>
    operator==(phosphor::network::InAddrAny lhs, T rhs) noexcept
{
    return phosphor::network::detail::veq(rhs, lhs);
}

auto& operator<<(auto& os, ether_addr v)
{
    return os << phosphor::network::detail::ToStrBuf<ether_addr>{}(v);
}

auto& operator<<(auto& os, in_addr v)
{
    return os << phosphor::network::detail::ToStrBuf<in_addr>{}(v);
}

auto& operator<<(auto& os, in6_addr v)
{
    return os << phosphor::network::detail::ToStrBuf<in6_addr>{}(v);
}

auto& operator<<(auto& os, phosphor::network::InAddrAny v)
{
    phosphor::network::detail::ToStrBuf<phosphor::network::InAddrAny> tsb;
    return os << tsb(v);
}

auto& operator<<(auto& os, phosphor::network::IfAddr v)
{
    phosphor::network::detail::ToStrBuf<phosphor::network::IfAddr> tsb;
    return os << tsb(v);
}

namespace phosphor::network
{

/** @brief Contains all of the object information about the interface */
struct AllIntfInfo
{
    InterfaceInfo intf;
    std::optional<in_addr> defgw4 = std::nullopt;
    std::optional<in6_addr> defgw6 = std::nullopt;
    std::unordered_map<IfAddr, AddressInfo> addrs = {};
    std::unordered_map<InAddrAny, NeighborInfo> staticNeighs = {};
};

} // namespace phosphor::network
