# Copyright (c) 2012,2019 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2005 The Regents of The University of Michigan
# Copyright (c) 2010 Advanced Micro Devices, Inc.
# All rights reserved.
#
# 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: Nathan Binkert
#          Steve Reinhardt

from __future__ import print_function

import atexit
import os
import sys

# import the wrapped C++ functions
import _m5.drain
import _m5.core
from _m5.stats import updateEvents as updateStatEvents

from . import stats
from . import SimObject
from . import ticks
from . import objects
from m5.util.dot_writer import do_dot, do_dvfs_dot
from m5.util.dot_writer_ruby import do_ruby_dot

from .util import fatal
from .util import attrdict

# define a MaxTick parameter, unsigned 64 bit
MaxTick = 2**64 - 1

_memory_modes = {
    "atomic" : objects.params.atomic,
    "timing" : objects.params.timing,
    "atomic_noncaching" : objects.params.atomic_noncaching,
    }

_drain_manager = _m5.drain.DrainManager.instance()

# The final hook to generate .ini files.  Called from the user script
# once the config is built.
def instantiate(ckpt_dir=None):
    from m5 import options

    root = objects.Root.getInstance()

    if not root:
        fatal("Need to instantiate Root() before calling instantiate()")

    # we need to fix the global frequency
    ticks.fixGlobalFrequency()

    # Make sure SimObject-valued params are in the configuration
    # hierarchy so we catch them with future descendants() walks
    for obj in root.descendants(): obj.adoptOrphanParams()

    # Unproxy in sorted order for determinism
    for obj in root.descendants(): obj.unproxyParams()

    if options.dump_config:
        ini_file = open(os.path.join(options.outdir, options.dump_config), 'w')
        # Print ini sections in sorted order for easier diffing
        for obj in sorted(root.descendants(), key=lambda o: o.path()):
            obj.print_ini(ini_file)
        ini_file.close()

    if options.json_config:
        try:
            import json
            json_file = open(
                os.path.join(options.outdir, options.json_config), 'w')
            d = root.get_config_as_dict()
            json.dump(d, json_file, indent=4)
            json_file.close()
        except ImportError:
            pass

    do_dot(root, options.outdir, options.dot_config)
    do_ruby_dot(root, options.outdir, options.dot_config)

    # Initialize the global statistics
    stats.initSimStats()

    # Create the C++ sim objects and connect ports
    for obj in root.descendants(): obj.createCCObject()
    for obj in root.descendants(): obj.connectPorts()

    # Do a second pass to finish initializing the sim objects
    for obj in root.descendants(): obj.init()

    # Do a third pass to initialize statistics
    for obj in root.descendants(): obj.regStats()

    # Do a fourth pass to initialize probe points
    for obj in root.descendants(): obj.regProbePoints()

    # Do a fifth pass to connect probe listeners
    for obj in root.descendants(): obj.regProbeListeners()

    # We want to generate the DVFS diagram for the system. This can only be
    # done once all of the CPP objects have been created and initialised so
    # that we are able to figure out which object belongs to which domain.
    if options.dot_dvfs_config:
        do_dvfs_dot(root, options.outdir, options.dot_dvfs_config)

    # We're done registering statistics.  Enable the stats package now.
    stats.enable()

    # Restore checkpoint (if any)
    if ckpt_dir:
        _drain_manager.preCheckpointRestore()
        ckpt = _m5.core.getCheckpoint(ckpt_dir)
        _m5.core.unserializeGlobals(ckpt);
        for obj in root.descendants(): obj.loadState(ckpt)
    else:
        for obj in root.descendants(): obj.initState()

    # Check to see if any of the stat events are in the past after resuming from
    # a checkpoint, If so, this call will shift them to be at a valid time.
    updateStatEvents()

need_startup = True
def simulate(*args, **kwargs):
    global need_startup

    if need_startup:
        root = objects.Root.getInstance()
        for obj in root.descendants(): obj.startup()
        need_startup = False

        # Python exit handlers happen in reverse order.
        # We want to dump stats last.
        atexit.register(stats.dump)

        # register our C++ exit callback function with Python
        atexit.register(_m5.core.doExitCleanup)

        # Reset to put the stats in a consistent state.
        stats.reset()

    if _drain_manager.isDrained():
        _drain_manager.resume()

    return _m5.event.simulate(*args, **kwargs)

def drain():
    """Drain the simulator in preparation of a checkpoint or memory mode
    switch.

    This operation is a no-op if the simulator is already in the
    Drained state.

    """

    # Try to drain all objects. Draining might not be completed unless
    # all objects return that they are drained on the first call. This
    # is because as objects drain they may cause other objects to no
    # longer be drained.
    def _drain():
        # Try to drain the system. The drain is successful if all
        # objects are done without simulation. We need to simulate
        # more if not.
        if _drain_manager.tryDrain():
            return True

        # WARNING: if a valid exit event occurs while draining, it
        # will not get returned to the user script
        exit_event = _m5.event.simulate()
        while exit_event.getCause() != 'Finished drain':
            exit_event = simulate()

        return False

    # Don't try to drain a system that is already drained
    is_drained = _drain_manager.isDrained()
    while not is_drained:
        is_drained = _drain()

    assert _drain_manager.isDrained(), "Drain state inconsistent"

def memWriteback(root):
    for obj in root.descendants():
        obj.memWriteback()

def memInvalidate(root):
    for obj in root.descendants():
        obj.memInvalidate()

def checkpoint(dir):
    root = objects.Root.getInstance()
    if not isinstance(root, objects.Root):
        raise TypeError("Checkpoint must be called on a root object.")

    drain()
    memWriteback(root)
    print("Writing checkpoint")
    _m5.core.serializeAll(dir)

def _changeMemoryMode(system, mode):
    if not isinstance(system, (objects.Root, objects.System)):
        raise TypeError("Parameter of type '%s'.  Must be type %s or %s." % \
              (type(system), objects.Root, objects.System))
    if system.getMemoryMode() != mode:
        system.setMemoryMode(mode)
    else:
        print("System already in target mode. Memory mode unchanged.")

def switchCpus(system, cpuList, verbose=True):
    """Switch CPUs in a system.

    Note: This method may switch the memory mode of the system if that
    is required by the CPUs. It may also flush all caches in the
    system.

    Arguments:
      system -- Simulated system.
      cpuList -- (old_cpu, new_cpu) tuples
    """

    if verbose:
        print("switching cpus")

    if not isinstance(cpuList, list):
        raise RuntimeError("Must pass a list to this function")
    for item in cpuList:
        if not isinstance(item, tuple) or len(item) != 2:
            raise RuntimeError("List must have tuples of (oldCPU,newCPU)")

    old_cpus = [old_cpu for old_cpu, new_cpu in cpuList]
    new_cpus = [new_cpu for old_cpu, new_cpu in cpuList]
    old_cpu_set = set(old_cpus)
    memory_mode_name = new_cpus[0].memory_mode()
    for old_cpu, new_cpu in cpuList:
        if not isinstance(old_cpu, objects.BaseCPU):
            raise TypeError("%s is not of type BaseCPU" % old_cpu)
        if not isinstance(new_cpu, objects.BaseCPU):
            raise TypeError("%s is not of type BaseCPU" % new_cpu)
        if new_cpu in old_cpu_set:
            raise RuntimeError(
                "New CPU (%s) is in the list of old CPUs." % (old_cpu,))
        if not new_cpu.switchedOut():
            raise RuntimeError("New CPU (%s) is already active." % (new_cpu,))
        if not new_cpu.support_take_over():
            raise RuntimeError(
                "New CPU (%s) does not support CPU handover." % (old_cpu,))
        if new_cpu.memory_mode() != memory_mode_name:
            raise RuntimeError(
                "%s and %s require different memory modes." % (new_cpu,
                                                               new_cpus[0]))
        if old_cpu.switchedOut():
            raise RuntimeError("Old CPU (%s) is inactive." % (new_cpu,))
        if not old_cpu.support_take_over():
            raise RuntimeError(
                "Old CPU (%s) does not support CPU handover." % (old_cpu,))

    try:
        memory_mode = _memory_modes[memory_mode_name]
    except KeyError:
        raise RuntimeError("Invalid memory mode (%s)" % memory_mode_name)

    drain()

    # Now all of the CPUs are ready to be switched out
    for old_cpu, new_cpu in cpuList:
        old_cpu.switchOut()

    # Change the memory mode if required. We check if this is needed
    # to avoid printing a warning if no switch was performed.
    if system.getMemoryMode() != memory_mode:
        # Flush the memory system if we are switching to a memory mode
        # that disables caches. This typically happens when switching to a
        # hardware virtualized CPU.
        if memory_mode == objects.params.atomic_noncaching:
            memWriteback(system)
            memInvalidate(system)

        _changeMemoryMode(system, memory_mode)

    for old_cpu, new_cpu in cpuList:
        new_cpu.takeOverFrom(old_cpu)

def notifyFork(root):
    for obj in root.descendants():
        obj.notifyFork()

fork_count = 0
def fork(simout="%(parent)s.f%(fork_seq)i"):
    """Fork the simulator.

    This function forks the simulator. After forking the simulator,
    the child process gets its output files redirected to a new output
    directory. The default name of the output directory is the same as
    the parent with the suffix ".fN" added where N is the fork
    sequence number. The name of the output directory can be
    overridden using the simout keyword argument.

    Output file formatting dictionary:
      parent -- Path to the parent process's output directory.
      fork_seq -- Fork sequence number.
      pid -- PID of the child process.

    Keyword Arguments:
      simout -- New simulation output directory.

    Return Value:
      pid of the child process or 0 if running in the child.
    """
    from m5 import options
    global fork_count

    if not _m5.core.listenersDisabled():
        raise RuntimeError("Can not fork a simulator with listeners enabled")

    drain()

    try:
        pid = os.fork()
    except OSError as e:
        raise e

    if pid == 0:
        # In child, notify objects of the fork
        root = objects.Root.getInstance()
        notifyFork(root)
        # Setup a new output directory
        parent = options.outdir
        options.outdir = simout % {
                "parent" : parent,
                "fork_seq" : fork_count,
                "pid" : os.getpid(),
                }
        _m5.core.setOutputDir(options.outdir)
    else:
        fork_count += 1

    return pid

from _m5.core import disableAllListeners, listenersDisabled
from _m5.core import listenersLoopbackOnly
from _m5.core import curTick
