/*
 * 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/ext/core/sc_main.hh"
#include "systemc/ext/core/sc_time.hh"
#include "systemc/ext/utils/sc_report_handler.hh"

namespace sc_core
{

namespace
{

const char *TimeUnitNames[] = {
    [SC_FS] = "fs",
    [SC_PS] = "ps",
    [SC_NS] = "ns",
    [SC_US] = "us",
    [SC_MS] = "ms",
    [SC_SEC] = "s"
};

double TimeUnitScale[] = {
    [SC_FS] = 1.0e-15,
    [SC_PS] = 1.0e-12,
    [SC_NS] = 1.0e-9,
    [SC_US] = 1.0e-6,
    [SC_MS] = 1.0e-3,
    [SC_SEC] = 1.0
};

Tick TimeUnitFrequency[] = {
    [SC_FS] = 1ULL * 1000 * 1000 * 1000 * 1000 * 1000,
    [SC_PS] = 1ULL * 1000 * 1000 * 1000 * 1000,
    [SC_NS] = 1ULL * 1000 * 1000 * 1000,
    [SC_US] = 1ULL * 1000 * 1000,
    [SC_MS] = 1ULL * 1000,
    [SC_SEC] = 1ULL
};

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 = 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, 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
{
    if (val == 0) {
        os << "0 s";
    } else {
        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.
        sc_time_unit tu = SC_SEC;
        while (tu > 1 && (frequency % 1000 == 0)) {
            tu = (sc_time_unit)((int)tu - 1);
            frequency /= 1000;
        }

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

        // Scale our integer value by the period.
        uint64_t scaled = val * period;

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

        os << scaled << ' ' << TimeUnitNames[tu];
    }
}

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)
{
    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
    return sc_time();
}

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("(E514) set time resolution failed",
                "value not positive");
    }
    double dummy;
    if (modf(log10(d), &dummy) != 0.0) {
        SC_REPORT_ERROR("(E514) set time resolution failed",
                "value not a power of ten");
    }
    if (sc_is_running()) {
        SC_REPORT_ERROR("(E514) set time resolution failed",
                "simulation running");
    }
    static bool specified = false;
    if (specified) {
        SC_REPORT_ERROR("(E514) set time resolution failed",
                "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("(E514) set time resolution failed",
                "sc_time object(s) constructed");
    }

    double seconds = d * TimeUnitScale[tu];
    if (seconds < TimeUnitScale[SC_FS]) {
        SC_REPORT_ERROR("(E514) set time resolution failed",
                "value smaller than 1 fs");
    }

    if (seconds > defaultUnit) {
        SC_REPORT_WARNING(
                "(W516) default time unit changed to time resolution", "");
        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 = 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("(E515) set default time unit failed",
                "value not positive");
    }
    double dummy;
    if (modf(log10(d), &dummy) != 0.0) {
        SC_REPORT_ERROR("(E515) set default time unit failed",
                "value not a power of ten");
    }
    if (sc_is_running()) {
        SC_REPORT_ERROR("(E515) set default time unit failed",
                "simulation running");
    }
    static bool specified = false;
    if (specified) {
        SC_REPORT_ERROR("(E515) set default time unit failed",
                "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("(E515) set default time unit failed",
                "sc_time object(s) constructed");
    }

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

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

sc_time_tuple::sc_time_tuple(const sc_time &)
{
    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
}

bool
sc_time_tuple::has_value() const
{
    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
    return false;
}

sc_dt::uint64
sc_time_tuple::value() const
{
    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
    return 0;
}

const char *
sc_time_tuple::unit_symbol() const
{
    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
    return "";
}

double
sc_time_tuple::to_double() const
{
    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
    return 0.0;
}

std::string
sc_time_tuple::to_string() const
{
    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
    return "";
}

} // namespace sc_core
