#ifndef HELPER_H
#define HELPER_H

#include <ctime>
#include <string>
#include <sstream>
#include <fstream>
/* custom namespace to store custom datatypes */
namespace Helper {

    template <class T>
    std::string ToString(const T &);

    struct DateTime {
        int date, month, year, hour, minutes, seconds;
        DateTime(){
            time_t ms;
            time(&ms);

            struct tm *info = localtime(&ms);

            /* formatting data from above pointer info */
            date = info->tm_mday;
            month = info->tm_mon+1; /*January is represented as 0 therefore 1 is added to increment */
            year = 1900 + info->tm_year; /* // reference year since C came in the 70s and locatime returns time from that particular day until present day */
            minutes = info->tm_min;
            hour = info->tm_hour;
            seconds = info->tm_sec;
        }
        DateTime(int date, int month, int year, int hour, int minutes, int seconds) : date(date), month(month), 
                year(year), hour(hour), minutes(minutes), seconds(seconds) {}
        DateTime(int date, int month, int year) : date(date), month(month), year(year), hour(0), minutes(0), 
                seconds(0) {}
        
        /* return current datetime */
        DateTime Now() const {
            return DateTime();
        }

        /* formatting date as DD.MM.YYYY */
        std::string GetDateString() const {
            return std::string( date < 10 ? "0" : "") + ToString(date) + std::string( month < 10 ? ".0" : ".") + 
                            ToString(month) + "." + ToString(year);
        }

        /*formatting time as HH:MM:SS and setting default separator as ':' */
        std::string GetTimeString(const std::string &sep = ":") const {
            return std::string(hour < 10 ? "0" : "") + ToString(hour) + sep + std::string(minutes < 10 ? "0" : "") 
                                + ToString(month) + sep + std::string(seconds < 10 ? sep : "") + ToString(seconds);
        }

        /* concatenating above functions */
        std::string GetDateTimeString(const std::string &sep = ":") const {
            return GetDateString() + " " + GetTimeString(sep);
        }
    };

    template <class T>

    /* Function to convert generic input into string. It can receive any input that supports insertion operator. */
    std::string ToString(const T &e) {
        std::ostringstream s;
        s << e;
        return s.str();
    }

    /* Reports behaviour of keylogger (for example, any problems encountered by keylogger) */
    void WriteAppLog(const std::string &str){
        std::ofstream file("AppLog.txt", std::ios::app);
        file << "[" << Helper::DateTime().GetDateTimeString() << "]" << "\n" << str << std::endl << "\n";
        file.close();
    }
}
#endif