/*
   HARK Library
   Copyright (C) 2021 Honda Research Institute Japan Inc.
 */

#include "hark-lib/timepoint.h"

#include <math.h>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <iomanip>

namespace hark
{
    // class Time
    Time::Time()
    {
    }

    Time::Time(std::chrono::system_clock::time_point &t) : time(t)
    {
    }

    void
    Time::setTime(std::chrono::system_clock::time_point &t)
    {
        this->time = t;
    }

    void
    Time::setLocalTime()
    {
        this->time = std::chrono::system_clock::now();
    }

    void
    Time::printTime()
    {
        std::vector<std::string> strMonList = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
        std::ostringstream sout;
        std::time_t tt = std::chrono::system_clock::to_time_t(this->time);
        const tm* lt = std::localtime(&tt);
        auto us = std::chrono::time_point_cast<std::chrono::microseconds>(this->time);

        sout << (lt->tm_year + 1900)
             << "-" << strMonList[lt->tm_mon]
             << "-" << std::setfill('0') << std::setw(2) << lt->tm_mday
             << " " << std::setfill('0') << std::setw(2) << lt->tm_hour
             << ":" << std::setfill('0') << std::setw(2) << lt->tm_min
             << ":" << std::setfill('0') << std::setw(2) << lt->tm_sec
             << "." << std::setfill('0') << std::setw(6)
             << us.time_since_epoch().count() % 1000000;
        std::cout << sout.str() << std::endl;
    }

    // class TimeStamp
    TimeStamp::TimeStamp()
    {
        this->time.tv_sec = 0;
        this->time.tv_usec = 0;
    }

    TimeStamp::TimeStamp(const TimeStamp &t) : time(t.time)
    {
    }

    TimeStamp::TimeStamp(const struct timeval &t) : time(t)
    {
    }

    TimeStamp::TimeStamp(const long int &sec, const long int &usec)
    {
        this->time.tv_sec = sec;
        this->time.tv_usec = usec;
    }

    void
    TimeStamp::setTime(const TimeStamp &t)
    {
        this->time = t.time;
    }

    void
    TimeStamp::setTime(const struct timeval &t)
    {
        this->time = t;
    }

    void
    TimeStamp::setTime(const long int &sec, const long int &usec)
    {
        this->time.tv_sec = sec;
        this->time.tv_usec = usec;
    }

    void
    TimeStamp::setLocalTime()
    {
        //gettimeofday(&this->time, nullptr);
        auto now_sec = std::chrono::system_clock::now();
        this->time.tv_sec = std::chrono::system_clock::to_time_t(now_sec);
        auto now_usec = std::chrono::time_point_cast<std::chrono::microseconds>(now_sec);
        this->time.tv_usec = now_usec.time_since_epoch().count() % 1000000;
    }

    void
    TimeStamp::printTime()
    {
        std::vector<std::string> strMonList = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
        std::ostringstream sout;
        const tm* lt = std::localtime(&this->time.tv_sec);

        sout << (lt->tm_year + 1900)
             << "-" << strMonList[lt->tm_mon]
             << "-" << std::setfill('0') << std::setw(2) << lt->tm_mday
             << " " << std::setfill('0') << std::setw(2) << lt->tm_hour
             << ":" << std::setfill('0') << std::setw(2) << lt->tm_min
             << ":" << std::setfill('0') << std::setw(2) << lt->tm_sec
             << "." << std::setfill('0') << std::setw(6)
             << this->time.tv_usec;
        std::cout << sout.str() << std::endl;
    }
}

/* end of file */
