#include "slp.hpp"

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

#include <algorithm>

#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(slp::CONF_FILE);
    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(slp::CONF_FILE);
    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(
    const std::string& filename)
{
    using namespace std::string_literals;
    /*Conf File format would be
      ServiceName serviceType Port */

    slp::handler::internal::ServiceList svcLst;

    std::ifstream readFile(filename);
    slp::ConfigData service;
    //Read all the service from the file
    while (readFile >> service)
    {
        std::string tmp = "service:"s + service.name;
        service.name = tmp;
        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
