/*
 * Copyright 2018 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include <sstream>
#include <vector>

#include "base/logging.hh"
#include "base/types.hh"
#include "python/pybind11/pybind.hh"
#include "sim/core.hh"
#include "systemc/core/python.hh"
#include "systemc/core/time.hh"
#include "systemc/ext/core/messages.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/core/sc_time.hh"
#include "systemc/ext/utils/sc_report_handler.hh"

namespace sc_core
{

namespace
{

bool timeFixed = false;
bool pythonReady = false;

struct SetInfo
{
    SetInfo(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu) :
        time(time), d(d), tu(tu)
    {}

    ::sc_core::sc_time *time;
    double d;
    ::sc_core::sc_time_unit tu;
};
std::vector<SetInfo> toSet;

void
setWork(sc_time *time, double d, ::sc_core::sc_time_unit tu)
{
    double scale = sc_gem5::TimeUnitScale[tu] * SimClock::Float::s;
    // Accellera claims there is a linux bug, and that these next two
    // lines work around them.
    volatile double tmp = d * scale + 0.5;
    *time = sc_time::from_value(static_cast<uint64_t>(tmp));
}

void
fixTime()
{
    auto ticks = pybind11::module::import("m5.ticks");
    auto fix_global_frequency = ticks.attr("fixGlobalFrequency");
    fix_global_frequency();

    for (auto &t: toSet)
        setWork(t.time, t.d, t.tu);
    toSet.clear();
}

void
attemptToFixTime()
{
    // Only fix time once.
    if (!timeFixed) {
        timeFixed = true;

        // If we've run, python is working and we haven't fixed time yet.
        if (pythonReady)
            fixTime();
    }
}

void
setGlobalFrequency(Tick ticks_per_second)
{
    auto ticks = pybind11::module::import("m5.ticks");
    auto set_global_frequency = ticks.attr("setGlobalFrequency");
    set_global_frequency(ticks_per_second);
    fixTime();
}

void
set(::sc_core::sc_time *time, double d, ::sc_core::sc_time_unit tu)
{
    if (d != 0)
        attemptToFixTime();
    if (pythonReady) {
        // Time should be working. Set up this sc_time.
        setWork(time, d, tu);
    } else {
        // Time isn't set up yet. Defer setting up this sc_time.
        toSet.emplace_back(time, d, tu);
    }
}

class TimeSetter : public ::sc_gem5::PythonReadyFunc
{
  public:
    TimeSetter() : ::sc_gem5::PythonReadyFunc() {}

    void
    run() override
    {
        // Record that we've run and python/pybind should be usable.
        pythonReady = true;

        // If time is already fixed, let python know.
        if (timeFixed)
            fixTime();
    }
} timeSetter;

double defaultUnit = 1.0e-9;

} // anonymous namespace

sc_time::sc_time() : val(0) {}

sc_time::sc_time(double d, sc_time_unit tu)
{
    val = 0;
    set(this, d, tu);
}

sc_time::sc_time(const sc_time &t)
{
    val = t.val;
}

sc_time::sc_time(double d, const char *unit)
{
    sc_time_unit tu;
    for (tu = SC_FS; tu <= SC_SEC; tu = (sc_time_unit)(tu + 1)) {
        if (strcmp(unit, sc_gem5::TimeUnitNames[tu]) == 0 ||
            strcmp(unit, sc_gem5::TimeUnitConstantNames[tu]) == 0) {
            break;
        }
    }

    if (tu > SC_SEC) {
        SC_REPORT_ERROR(SC_ID_TIME_CONVERSION_FAILED_,"invalid unit given");
        val = 0;
        return;
    }
    set(this, d, tu);
}

sc_time::sc_time(double d, bool scale)
{
    double scaler = scale ? defaultUnit : SimClock::Float::Hz;
    set(this, d * scaler, SC_SEC);
}

sc_time::sc_time(sc_dt::uint64 v, bool scale)
{
    double scaler = scale ? defaultUnit : SimClock::Float::Hz;
    set(this, static_cast<double>(v) * scaler, SC_SEC);
}

sc_time &
sc_time::operator = (const sc_time &t)
{
    val = t.val;
    return *this;
}

sc_dt::uint64
sc_time::value() const
{
    return val;
}

double
sc_time::to_double() const
{
    return static_cast<double>(val);
}
double
sc_time::to_seconds() const
{
    return to_double() * SimClock::Float::Hz;
}

const std::string
sc_time::to_string() const
{
    std::ostringstream ss;
    print(ss);
    return ss.str();
}

bool
sc_time::operator == (const sc_time &t) const
{
    return val == t.val;
}

bool
sc_time::operator != (const sc_time &t) const
{
    return val != t.val;
}

bool
sc_time::operator < (const sc_time &t) const
{
    return val < t.val;
}

bool
sc_time::operator <= (const sc_time &t) const
{
    return val <= t.val;
}

bool
sc_time::operator > (const sc_time &t) const
{
    return val > t.val;
}

bool
sc_time::operator >= (const sc_time &t) const
{
    return val >= t.val;
}

sc_time &
sc_time::operator += (const sc_time &t)
{
    val += t.val;
    return *this;
}

sc_time &
sc_time::operator -= (const sc_time &t)
{
    val -= t.val;
    return *this;
}

sc_time &
sc_time::operator *= (double d)
{
    val = static_cast<int64_t>(static_cast<double>(val) * d + 0.5);
    return *this;
}

sc_time &
sc_time::operator /= (double d)
{
    val = static_cast<int64_t>(static_cast<double>(val) / d + 0.5);
    return *this;
}

void
sc_time::print(std::ostream &os) const
{
    os << sc_time_tuple(*this).to_string();
}

sc_time
sc_time::from_value(sc_dt::uint64 u)
{
    if (u)
        attemptToFixTime();
    sc_time t;
    t.val = u;
    return t;
}

sc_time
sc_time::from_seconds(double d)
{
    sc_time t;
    set(&t, d, SC_SEC);
    return t;
}

sc_time
sc_time::from_string(const char *str)
{
    char *end = nullptr;

    double d = str ? std::strtod(str, &end) : 0.0;
    if (str == end || d < 0.0) {
        SC_REPORT_ERROR(SC_ID_TIME_CONVERSION_FAILED_, "invalid value given");
        return SC_ZERO_TIME;
    }

    while (*end && std::isspace(*end))
        end++;

    return sc_time(d, end);
}

const sc_time
operator + (const sc_time &a, const sc_time &b)
{
    return sc_time::from_value(a.value() + b.value());
}

const sc_time
operator - (const sc_time &a, const sc_time &b)
{
    return sc_time::from_value(a.value() - b.value());
}

const sc_time
operator * (const sc_time &t, double d)
{
    volatile double tmp = static_cast<double>(t.value()) * d + 0.5;
    return sc_time::from_value(static_cast<int64_t>(tmp));
}

const sc_time
operator * (double d, const sc_time &t)
{
    volatile double tmp = d * static_cast<double>(t.value()) + 0.5;
    return sc_time::from_value(static_cast<int64_t>(tmp));
}

const sc_time
operator / (const sc_time &t, double d)
{
    volatile double tmp = static_cast<double>(t.value()) / d + 0.5;
    return sc_time::from_value(static_cast<int64_t>(tmp));
}

double
operator / (const sc_time &t1, const sc_time &t2)
{
    return t1.to_double() / t2.to_double();
}

std::ostream &
operator << (std::ostream &os, const sc_time &t)
{
    t.print(os);
    return os;
}

const sc_time SC_ZERO_TIME;

void
sc_set_time_resolution(double d, sc_time_unit tu)
{
    if (d <= 0.0)
        SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "value not positive");

    double dummy;
    if (modf(log10(d), &dummy) != 0.0) {
        SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_,
                "value not a power of ten");
    }
    if (sc_is_running())
        SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "simulation running");

    static bool specified = false;
    if (specified)
        SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "already specified");

    // This won't detect the timescale being fixed outside of systemc, but
    // it's at least some protection.
    if (timeFixed) {
        SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_,
                "sc_time object(s) constructed");
    }

    double seconds = d * sc_gem5::TimeUnitScale[tu];
    if (seconds < sc_gem5::TimeUnitScale[SC_FS])
        SC_REPORT_ERROR(SC_ID_SET_TIME_RESOLUTION_, "value smaller than 1 fs");

    if (seconds > defaultUnit) {
        SC_REPORT_WARNING(SC_ID_DEFAULT_TIME_UNIT_CHANGED_, "");
        defaultUnit = seconds;
    }

    // Get rid of fractional parts of d.
    while (d < 1.0 && tu > SC_FS) {
        d *= 1000;
        tu = (sc_time_unit)(tu - 1);
    }

    Tick ticks_per_second =
        sc_gem5::TimeUnitFrequency[tu] / static_cast<Tick>(d);
    setGlobalFrequency(ticks_per_second);
    specified = true;
}

sc_time
sc_get_time_resolution()
{
    return sc_time::from_value(1);
}

const sc_time &
sc_max_time()
{
    static const sc_time MaxScTime = sc_time::from_value(MaxTick);
    return MaxScTime;
}

void
sc_set_default_time_unit(double d, sc_time_unit tu)
{
    if (d < 0.0)
        SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "value not positive");

    double dummy;
    if (modf(log10(d), &dummy) != 0.0) {
        SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_,
                "value not a power of ten");
    }
    if (sc_is_running())
        SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "simulation running");

    static bool specified = false;
    if (specified) {
        SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_, "already specified");
    }
    // This won't detect the timescale being fixed outside of systemc, but
    // it's at least some protection.
    if (timeFixed) {
        SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_,
                "sc_time object(s) constructed");
    }

    // Normalize d to seconds.
    defaultUnit = d * sc_gem5::TimeUnitScale[tu];
    specified = true;

    double resolution = SimClock::Float::Hz;
    if (resolution == 0.0)
        resolution = sc_gem5::TimeUnitScale[SC_PS];
    if (defaultUnit < resolution) {
        SC_REPORT_ERROR(SC_ID_SET_DEFAULT_TIME_UNIT_,
                "value smaller than time resolution");
    }
}

sc_time
sc_get_default_time_unit()
{
    return sc_time(defaultUnit, SC_SEC);
}

sc_time_tuple::sc_time_tuple(const sc_time &t) :
    _value(), _unit(SC_SEC), _set(true)
{
    if (!t.value())
        return;

    Tick frequency = SimClock::Frequency;

    // Shrink the frequency by scaling down the time period, ie converting
    // it from cycles per second to cycles per millisecond, etc.
    while (_unit > 1 && (frequency % 1000 == 0)) {
        _unit = (sc_time_unit)((int)_unit - 1);
        frequency /= 1000;
    }

    // Convert the frequency into a period.
    Tick period;
    if (frequency > 1) {
        _unit = (sc_time_unit)((int)_unit - 1);
        period = 1000 / frequency;
    } else {
        period = frequency;
    }

    // Scale our integer value by the period.
    _value = t.value() * period;

    // Shrink the scaled time value by increasing the size of the units
    // it's measured by, avoiding fractional parts.
    while (_unit < SC_SEC && (_value % 1000) == 0) {
        _unit = (sc_time_unit)((int)_unit + 1);
        _value /= 1000;
    }
}

bool
sc_time_tuple::has_value() const
{
    return _set;
}

sc_dt::uint64 sc_time_tuple::value() const { return _value; }

const char *
sc_time_tuple::unit_symbol() const
{
    return sc_gem5::TimeUnitNames[_unit];
}

double sc_time_tuple::to_double() const { return static_cast<double>(_value); }

std::string
sc_time_tuple::to_string() const
{
    std::ostringstream ss;
    ss << _value << ' ' << unit_symbol();
    return ss.str();
}

} // namespace sc_core
