#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);
        std::cerr << "SLP unable to read the service info\n";
        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);
        std::cerr << "SLP unable to read the service info\n";
        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);
        std::cerr << "SLP unable to find the service=" << svcName << "\n";
        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);
        std::cerr << "SLP unable to read the interface address\n";
        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)
    {
        std::cout << "SLP Processing Request="
                  << msg.header.functionID <<"\n";

        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
