# -*- coding: utf-8 -*-
# Copyright (c) 2019 The Regents of the University of California.
# 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: Jason Lowe-Power, Ayaz Akram, Hoa Nguyen

""" Script to run a SPEC benchmark in full system mode with gem5.

    Inputs:
    * This script expects the following as arguments:
        ** kernel:
                  This is a positional argument specifying the path to
                  vmlinux.
        ** disk:
                  This is a positional argument specifying the path to the
                  disk image containing the installed SPEC benchmarks.
        ** cpu:
                  This is a positional argument specifying the name of the
                  detailed CPU model. The names of the available CPU models
                  are available in the getDetailedCPUModel(cpu_name) function.
                  The function should be modified to add new CPU models.
                  Currently, the available CPU models are:
                    - kvm: this is not a detailed CPU model, ideal for testing.
                    - o3: DerivO3CPU.
                    - atomic: AtomicSimpleCPU.
                    - timing: TimingSimpleCPU.
        ** benchmark:
                  This is a positional argument specifying the name of the
                  SPEC benchmark to run. Most SPEC benchmarks are available.
                  Please follow this link to check the availability of the
                  benchmarks. The working benchmark matrix is near the end
                  of the page:
         (SPEC 2006) https://gem5art.readthedocs.io/en/latest/tutorials/spec2006-tutorial.html#appendix-i-working-spec-2006-benchmarks-x-cpu-model-table
         (SPEC 2017) https://gem5art.readthedocs.io/en/latest/tutorials/spec2017-tutorial.html#appendix-i-working-spec-2017-benchmarks-x-cpu-model-table
        ** size:
                  This is a positional argument specifying the size of the
                  benchmark. The available sizes are: ref, test, train.
        ** --no-copy-logs:
                  This is an optional argument specifying the reports of
                  the benchmark run is not copied to the output folder.
                  The reports are copied by default.
        ** --allow-listeners:
                  This is an optional argument specifying gem5 to open GDB
                  listening ports. Usually, the ports are opened for debugging
                  purposes.
                  By default, the ports are off.
"""
import os

import m5
import m5.ticks
from m5.objects import *

import argparse

from system import *


def writeBenchScript(dir, benchmark_name, size, output_path):
    """
    This method creates a script in dir which will be eventually
    passed to the simulated system (to run a specific benchmark
    at bootup).
    """
    input_file_name = '{}/run_{}_{}'.format(dir, benchmark_name, size)
    with open(input_file_name, "w") as f:
        f.write('{} {} {}'.format(benchmark_name, size, output_path))
    return input_file_name

def parse_arguments():
    parser = argparse.ArgumentParser(description=
                                "gem5 config file to run SPEC benchmarks")
    parser.add_argument("kernel", type = str, help = "Path to vmlinux")
    parser.add_argument("disk", type = str,
                  help = "Path to the disk image containing SPEC benchmarks")
    parser.add_argument("cpu", type = str, help = "Name of the detailed CPU")
    parser.add_argument("mem_sys", type = str, help = "Name of the memory system")
    parser.add_argument("benchmark", type = str,
                        help = "Name of the SPEC benchmark")
    parser.add_argument("size", type = str,
                        help = "Available sizes: test, train, ref")
    parser.add_argument("-l", "--no-copy-logs", default = False,
                        action = "store_true",
                        help = "Not to copy SPEC run logs to the host system;"
                               "Logs are copied by default")
    parser.add_argument("-z", "--allow-listeners", default = False,
                        action = "store_true",
                        help = "Turn on ports;"
                               "The ports are off by default")
    return parser.parse_args()

def getDetailedCPUModel(cpu_name):
    '''
    Return the CPU model corresponding to the cpu_name.
    '''
    available_models = {"kvm": X86KvmCPU,
                        "o3": DerivO3CPU,
                        "atomic": AtomicSimpleCPU,
                        "timing": TimingSimpleCPU
                       }
    try:
        available_models["FlexCPU"] = FlexCPU
    except NameError:
        # FlexCPU is not defined
        pass
    # https://docs.python.org/3/library/stdtypes.html#dict.get
    # dict.get() returns None if the key does not exist
    return available_models.get(cpu_name)

def getBenchmarkName(benchmark_name):
    if benchmark_name.endswith("(base)"):
        benchmark_name = benchmark_name[:-6]
    return benchmark_name

def create_system(linux_kernel_path, disk_image_path, detailed_cpu_model, memory_system):
    # create the system we are going to simulate
    ruby_protocols = [ "MI_example", "MESI_Two_Level", "MOESI_CMP_directory"]
    if memory_system == 'classic':
        system = MySystem(kernel = linux_kernel_path,
                          disk = disk_image_path,
                          num_cpus = 1, # run the benchmark in a single thread
                          no_kvm = False,
                          TimingCPUModel = detailed_cpu_model)
    elif memory_system in ruby_protocols:
        system = MyRubySystem(kernel = linux_kernel_path,
                              disk = disk_image_path,
                              num_cpus = 1, # run the benchmark in a single thread
                              mem_sys = memory_system,
                              no_kvm = False,
                              TimingCPUModel = detailed_cpu_model)
    else:
        m5.fatal("Bad option for mem_sys, should be "
                 "{}, or 'classic'".format(', '.join(ruby_protocols)))

    # For workitems to work correctly
    # This will cause the simulator to exit simulation when the first work
    # item is reached and when the first work item is finished.
    system.work_begin_exit_count = 1
    system.work_end_exit_count = 1

    # set up the root SimObject and start the simulation
    root = Root(full_system = True, system = system)

    if system.getHostParallel():
        # Required for running kvm on multiple host cores.
        # Uses gem5's parallel event queue feature
        # Note: The simulator is quite picky about this number!
        root.sim_quantum = int(1e9) # 1 ms

    return root, system


def boot_linux():
    '''
    Output 1: False if errors occur, True otherwise
    Output 2: exit cause
    '''
    print("Booting Linux")
    exit_event = m5.simulate()
    exit_cause = exit_event.getCause()
    success = exit_cause == "m5_exit instruction encountered"
    if not success:
        print("Error while booting linux: {}".format(exit_cause))
        exit(1)
    print("Done booting Linux")
    return success, exit_cause

def run_spec_benchmark():
    '''
    Output 1: False if errors occur, True otherwise
    Output 2: exit cause
    '''
    print("Start running benchmark")
    exit_event = m5.simulate()
    exit_cause = exit_event.getCause()
    success = exit_cause == "m5_exit instruction encountered"
    if not success:
        print("Error while running benchmark: {}".format(exit_cause))
        exit(1)
    print("Benchmark done")
    return success, exit_cause

def copy_spec_logs():
    '''
    Output 1: False if errors occur, True otherwise
    Output 2: exit cause
    '''
    print("Copying SPEC logs")
    exit_event = m5.simulate()
    exit_cause = exit_event.getCause()
    success = exit_cause == "m5_exit instruction encountered"
    if not success:
        print("Error while copying SPEC log files: {}".format(exit_cause))
        exit(1)
    print("Copying done")
    return success, exit_cause

if __name__ == "__m5_main__":
    args = parse_arguments()

    cpu_name = args.cpu
    mem_sys = args.mem_sys
    benchmark_name = getBenchmarkName(args.benchmark)
    benchmark_size = args.size
    linux_kernel_path = args.kernel
    disk_image_path = args.disk
    no_copy_logs = args.no_copy_logs
    allow_listeners = args.allow_listeners

    if not no_copy_logs and not os.path.isabs(m5.options.outdir):
        print("Please specify the --outdir (output directory) of gem5"
              " in the form of an absolute path")
        print("An example: build/X86/gem5.opt --outdir /home/user/m5out/"
              " configs-spec-tests/run_spec ...")
        exit(1)

    output_dir = os.path.join(m5.options.outdir, "speclogs")

    # Get the DetailedCPU class from its name
    detailed_cpu = getDetailedCPUModel(cpu_name)
    if detailed_cpu == None:
        print("'{}' is not define in the config script.".format(cpu_name))
        print("Change getDeatiledCPUModel() in run_spec.py "
              "to add more CPU Models.")
        exit(1)

    if not benchmark_size in ["ref", "train", "test"]:
        print("Benchmark size must be one of the following: ref, train, test")
        exit(1)

    root, system = create_system(linux_kernel_path, disk_image_path,
                                 detailed_cpu, mem_sys)

    # Create and pass a script to the simulated system to run the required
    # benchmark
    system.readfile = writeBenchScript(m5.options.outdir, benchmark_name,
                                       benchmark_size, output_dir)

    # needed for long running jobs
    if not allow_listeners:
        m5.disableAllListeners()

    # instantiate all of the objects we've created above
    m5.instantiate()

    # booting linux
    success, exit_cause = boot_linux()

    # reset stats
    print("Reset stats")
    m5.stats.reset()

    # switch from KVM to detailed CPU
    if not cpu_name == "kvm":
        print("Switching to detailed CPU")
        system.switchCpus(system.cpu, system.detailed_cpu)
        print("Switching done")

    # running benchmark
    print("Benchmark: {}; Size: {}".format(benchmark_name, benchmark_size))
    success, exit_cause = run_spec_benchmark()

    # output the stats after the benchmark is complete
    print("Output stats")
    m5.stats.dump()

    if not no_copy_logs:
        # create the output folder
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # switch from detailed CPU to KVM
        if not cpu_name == "kvm":
            print("Switching to KVM")
            system.switchCpus(system.detailed_cpu, system.cpu)
            print("Switching done")

        # copying logs
        success, exit_cause = copy_spec_logs()
