# Copyright (c) 2015, 2020 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.
#
# 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.

from multiprocessing import Process
import sys
import os

import m5

_exit_normal = ("target called exit()", "m5_exit instruction encountered")

_exit_limit = ("simulate() limit reached",)

_exitcode_done = 0
_exitcode_fail = 1
_exitcode_checkpoint = 42


def _run_step(name, restore=None, interval=0.5):
    """
    Instantiate (optionally from a checkpoint if restore is set to the
    checkpoitn name) the system and run for interval seconds of
    simulated time. At the end of the simulation interval, create a
    checkpoint and exit.

    As this function is intended to run in its own process using the
    multiprocessing framework, the exit is a true call to exit which
    terminates the process. Exit codes are used to pass information to
    the parent.
    """
    if restore is not None:
        m5.instantiate(restore)
    else:
        m5.instantiate()

    e = m5.simulate(m5.ticks.fromSeconds(interval))
    cause = e.getCause()
    if cause in _exit_limit:
        m5.checkpoint(name)
        sys.exit(_exitcode_checkpoint)
    elif cause in _exit_normal:
        sys.exit(_exitcode_done)
    else:
        print("Test failed: Unknown exit cause: %s" % cause)
        sys.exit(_exitcode_fail)


def run_test(root, interval=0.5, max_checkpoints=5):
    """
    Run the simulated system for a fixed amount of time and take a
    checkpoint, then restore from the same checkpoint and run until
    the system calls m5 exit.
    """

    cpt_name = os.path.join(m5.options.outdir, "test.cpt")
    restore = None
    checkpointed = False

    for cpt_no in range(max_checkpoints):
        # Create a checkpoint from a separate child process. This enables
        # us to get back to a (mostly) pristine state and restart
        # simulation from the checkpoint.
        p = Process(
            target=_run_step,
            args=(cpt_name,),
            kwargs={"restore": restore, "interval": interval},
        )
        p.start()

        # Wait for the child to return
        p.join()

        # Restore from the checkpoint next iteration
        restore = cpt_name

        if p.exitcode == _exitcode_done:
            if checkpointed:
                print("Test done.", file=sys.stderr)
                sys.exit(0)
            else:
                print(
                    "Test done, but no checkpoint was created.",
                    file=sys.stderr,
                )
                sys.exit(1)
        elif p.exitcode == _exitcode_checkpoint:
            checkpointed = True
        else:
            print("Test failed.", file=sys.stderr)
            sys.exit(1)

    # Maximum number of checkpoints reached. Just run full-speed from
    # now on.
    m5.instantiate()
    e = m5.simulate()
    cause = e.getCause()
    if cause in _exit_normal:
        sys.exit(0)
    else:
        print("Test failed: Unknown exit cause: %s" % cause)
        sys.exit(1)
