#include <SimCore/UtilFunctions.hpp>
#include <arpa/inet.h>
#include <cmath>
#include <netdb.h>
#include <string>
#include <unistd.h>

namespace SimCore {


    std::vector<std::string> UtilFunctions::explode(std::string const & s, char delim)
    {
        std::vector<std::string> result;
        std::istringstream iss(s);

        for (std::string token; std::getline(iss, token, delim); )
        {
            result.push_back(std::move(token));
        }

        return result;
    }

     std::string UtilFunctions::implode(const std::vector<std::string> &v , char delim)
     {
            std::string ret;

        for(const auto &s : v) 
        {
            if(!ret.empty())
            {
                ret += delim;
            }
            ret += s;
        }
        return ret;
     }



    bool UtilFunctions::isNumber(const std::string& s)
    {
        return !s.empty() && std::find_if(s.begin(), 
            s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
    }

 void UtilFunctions::check_host_name(int hostname) { //This function returns host name for local computer
        if (hostname == -1) {
            perror("gethostname");
            exit(1);
        }
    }
    void UtilFunctions::check_host_entry(struct hostent * hostentry) { //find host info from host name
        if (hostentry == NULL){
            perror("gethostbyname");
            exit(1);
        }
    }
    void IP_formatter(char *IPbuffer) { //convert IP string to dotted decimal format
        if (NULL == IPbuffer) {
            perror("inet_ntoa");
            exit(1);
        }
    }

    std::string UtilFunctions::getOwnIP(){
        char host[256];
        char *IP;
        struct hostent *host_entry;
        int hostname;
        hostname = gethostname(host, sizeof(host)); //find the host name
        check_host_name(hostname);
        host_entry = gethostbyname(host); //find host information
        check_host_entry(host_entry);
        IP = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0])); //Convert into IP string


        return IP;
    };




     double UtilFunctions::DegToRad(double deg)
     {
        return deg * M_PI / 180.0;
     }
     double UtilFunctions::RadToDeg(double rad)
     {
        return rad * 180 / M_PI;
     }

}