#include "slp.hpp"

#include <arpa/inet.h>
#include <dirent.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <string.h>

#include <algorithm>

#include "config.h"
#include "endian.hpp"
#include "slp_meta.hpp"

namespace slp
{
namespace handler
{

namespace internal
{

buffer prepareHeader(const Message& req)
{
    uint8_t length =  slp::header::MIN_LEN +   /* 14 bytes for header     */
                      req.header.langtag.length() + /* Actual length of lang tag */
                      slp::response::SIZE_ERROR; /*  2 bytes for error code */

    buffer buff(length, 0);

    buff[slp::header::OFFSET_VERSION] = req.header.version;

    //will increment the function id from 1 as reply
    buff[slp::header::OFFSET_FUNCTION] = req.header.functionID + 1;

    std::copy_n(&length, slp::header::SIZE_LENGTH,
                buff.data() +
                slp::header::OFFSET_LENGTH);

    auto flags = endian::to_network(req.header.flags);

    std::copy_n((uint8_t*)&flags, slp::header::SIZE_FLAGS,
                buff.data() +
                slp::header::OFFSET_FLAGS);

    std::copy_n(req.header.extOffset.data(), slp::header::SIZE_EXT,
                buff.data() +
                slp::header::OFFSET_EXT);

    auto xid = endian::to_network(req.header.xid);

    std::copy_n((uint8_t*)&xid, slp::header::SIZE_XID,
                buff.data() +
                slp::header::OFFSET_XID);

    uint16_t langtagLen = req.header.langtag.length();
    langtagLen = endian::to_network(langtagLen);
    std::copy_n((uint8_t*)&langtagLen, slp::header::SIZE_LANG,
                buff.data() +
                slp::header::OFFSET_LANG_LEN);

    std::copy_n((uint8_t*)req.header.langtag.c_str(), req.header.langtag.length(),
                buff.data() +
                slp::header::OFFSET_LANG);
    return buff;

}

std::tuple<int, buffer> processSrvTypeRequest(
    const Message& req)
{

    /*
       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |      Service Location header (function = SrvTypeRply = 10)    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |           Error Code          |    length of <srvType-list>   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                       <srvtype--list>                         \
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    */

    buffer buff;

    //read the slp service info from conf and create the service type string
    slp::handler::internal::ServiceList svcList =
        slp::handler::internal::readSLPServiceInfo();
    if (svcList.size() <= 0)
    {
        buff.resize(0);
        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
    }

    std::string service;
    bool firstIteration = true;
    for_each(svcList.cbegin(), svcList.cend(),
             [&service, &firstIteration](const auto& svc)
    {
        if (firstIteration == true)
        {
            service = svc.first;
            firstIteration = false;
        }
        else
        {
            service += ",";
            service += svc.first;
        }
    });

    buff = prepareHeader(req);

    /* Need to modify the length and the function type field of the header
     * as it is dependent on the handler of the service */

    std::cout << "service=" << service.c_str() << "\n";

    uint8_t length =  buff.size() +   /* 14 bytes header + length of langtag */
                      slp::response::SIZE_ERROR +    /* 2 byte err code */
                      slp::response::SIZE_SERVICE +  /* 2 byte srvtype len */
                      service.length();


    buff.resize(length);

    std::copy_n(&length, slp::header::SIZE_LENGTH,
                buff.data() +
                slp::header::OFFSET_LENGTH);

    /* error code is already set to 0 moving to service type len */

    uint16_t serviceTypeLen = service.length();
    serviceTypeLen = endian::to_network(serviceTypeLen);

    std::copy_n((uint8_t*)&serviceTypeLen, slp::response::SIZE_SERVICE,
                buff.data() +
                slp::response::OFFSET_SERVICE_LEN);

    /* service type data */
    std::copy_n((uint8_t*)service.c_str(), service.length(),
                (buff.data() +
                 slp::response::OFFSET_SERVICE));

    return std::make_tuple(slp::SUCCESS, buff);
}

std::tuple<int, buffer> processSrvRequest(
    const Message& req)
{

    /*
          Service Reply
          0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |        Service Location header (function = SrvRply = 2)       |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |        Error Code             |        URL Entry count        |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |       <URL Entry 1>          ...       <URL Entry N>          \
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

         URL Entry
          0                   1                   2                   3
          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |   Reserved    |          Lifetime             |   URL Length  |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |URL len, contd.|            URL (variable length)              \
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |# of URL auths |            Auth. blocks (if any)              \
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    */

    buffer buff;
    //Get all the services which are registered
    slp::handler::internal::ServiceList svcList =
        slp::handler::internal::readSLPServiceInfo();
    if (svcList.size() <= 0)
    {
        buff.resize(0);
        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
    }

    //return error if serice type doesn't match
    auto& svcName = req.body.srvrqst.srvType;
    auto svcIt = svcList.find(svcName);
    if (svcIt == svcList.end())
    {
        buff.resize(0);
        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
    }
    //Get all the interface address
    auto ifaddrList = slp::handler::internal::getIntfAddrs();
    if (ifaddrList.size() <= 0)
    {
        buff.resize(0);
        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
    }

    buff = prepareHeader(req);
    //Calculate the length and resize the buffer
    uint8_t length =  buff.size() + /* 14 bytes header + length of langtag */
                      slp::response::SIZE_ERROR +    /* 2 bytes error code */
                      slp::response::SIZE_URL_COUNT; /* 2 bytes srvtype len */

    buff.resize(length);

    //Populate the url count
    uint16_t urlCount = ifaddrList.size();
    urlCount = endian::to_network(urlCount);

    std::copy_n((uint8_t*)&urlCount, slp::response::SIZE_URL_COUNT,
                buff.data() +
                slp::response::OFFSET_URL_ENTRY);

    //Find the service
    const slp::ConfigData& svc = svcIt->second;
    //Populate the URL Entrys
    auto pos = slp::response::OFFSET_URL_ENTRY + slp::response::SIZE_URL_COUNT;
    for (const auto& addr : ifaddrList)
    {
        std::string url = svc.name + ':' + svc.type +
                          "//" + addr + ',' + svc.port;


        buff.resize(buff.size() +
                    slp::response::SIZE_URL_ENTRY +
                    url.length());

        uint8_t reserved = 0;
        uint16_t auth = 0;
        uint16_t lifetime = endian::to_network<uint16_t>(slp::LIFETIME);
        uint16_t urlLength = url.length();

        std::copy_n((uint8_t*)&reserved, slp::response::SIZE_RESERVED,
                    buff.data() + pos);

        pos += slp::response::SIZE_RESERVED;


        std::copy_n((uint8_t*)&lifetime, slp::response::SIZE_LIFETIME,
                    buff.data() + pos);

        pos += slp::response::SIZE_LIFETIME;

        urlLength = endian::to_network(urlLength);
        std::copy_n((uint8_t*)&urlLength, slp::response::SIZE_URLLENGTH,
                    buff.data() + pos);
        pos += slp::response::SIZE_URLLENGTH;

        std::copy_n((uint8_t*)url.c_str(), url.length(),
                    buff.data() + pos);
        pos += url.length();

        std::copy_n((uint8_t*)&auth, slp::response::SIZE_AUTH,
                    buff.data() + pos);
        pos += slp::response::SIZE_AUTH;
    }
    uint8_t packetLength = buff.size();
    std::copy_n((uint8_t*)&packetLength, slp::header::SIZE_VERSION,
                buff.data() +
                slp::header::OFFSET_LENGTH);

    return std::make_tuple((int)slp::SUCCESS, buff);
}

std::list<std::string> getIntfAddrs()
{
    std::list<std::string> addrList;

    struct ifaddrs* ifaddr;
    // attempt to fill struct with ifaddrs
    if (getifaddrs(&ifaddr) == -1)
    {
        return addrList;
    }

    slp::deleted_unique_ptr<ifaddrs> ifaddrPtr(ifaddr, [](ifaddrs * addr)
    {
        freeifaddrs(addr);
    });

    ifaddr = nullptr;

    for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
    {
        // walk interfaces
        if (ifa->ifa_addr == nullptr)
        {
            continue;
        }

        // get only INET interfaces not ipv6
        if (ifa->ifa_addr->sa_family == AF_INET)
        {
            // if loopback, or not running ignore
            if ((ifa->ifa_flags & IFF_LOOPBACK) ||
                !(ifa->ifa_flags & IFF_RUNNING))
            {
                continue;
            }

            char tmp[INET_ADDRSTRLEN] = { 0 };

            inet_ntop(AF_INET,
                      &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr),
                      tmp,
                      sizeof(tmp));
            addrList.emplace_back(tmp);
        }
    }

    return addrList;
}

slp::handler::internal::ServiceList  readSLPServiceInfo()
{
    using namespace std::string_literals;
    slp::handler::internal::ServiceList svcLst;
    slp::ConfigData service;
    struct dirent* dent = nullptr;

    // Open the services dir and get the service info
    // from service files.
    // Service File format would be "ServiceName serviceType Port"
    DIR* dir = opendir(SERVICE_DIR);
    // wrap the pointer into smart pointer.
    slp::deleted_unique_ptr<DIR> dirPtr(dir, [](DIR * dir)
    {
        if (!dir)
        {
            closedir(dir);
        }
    });
    dir = nullptr;

    if (dirPtr.get())
    {
        while ((dent = readdir(dirPtr.get())) != NULL)
        {
            if (dent->d_type == DT_REG) //regular file
            {
                auto absFileName = std::string(SERVICE_DIR) + dent->d_name;
                std::ifstream readFile(absFileName);
                readFile >> service;
                service.name = "service:"s + service.name;
                svcLst.emplace(service.name, service);
            }
        }

    }
    return svcLst;
}
}//namespace internal

std::tuple<int, buffer> processRequest(
    const Message& msg)
{
    int rc = slp::SUCCESS;
    buffer resp(0);
    switch (msg.header.functionID)
    {
        case (uint8_t)slp::FunctionType::SRVTYPERQST:
            std::tie(rc, resp) = slp::handler::internal::processSrvTypeRequest(msg);
            break;
        case (uint8_t)slp::FunctionType::SRVRQST:
            std::tie(rc, resp) = slp::handler::internal::processSrvRequest(msg);
            break;
        default:
            rc = (uint8_t)slp::Error::MSG_NOT_SUPPORTED;
    }
    return std::make_tuple(rc, resp);
}

buffer processError(const Message& req,
                    uint8_t err)
{
    buffer buff;
    buff = slp::handler::internal::prepareHeader(req);

    std::copy_n(&err, slp::response::SIZE_ERROR,
                buff.data() +
                slp::response::OFFSET_ERROR);
    return buff;

}
}//namespace handler
}//namespace slp
