/*
 * Copyright (c) 2014 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.
 */

/**
 * @file
 *
 *  Example top level file for SystemC integration with C++-only
 *  instantiation.
 *
 *  Build with something like:
 *
 *      scons --without-python build/ARM/libgem5_opt.so
 *
 *      g++ -std=c++0x -Ibuild/ARM -Isrc -DTRACING_ON \
 *          -o gem5cxx.opt -Lbuild/ARM -lgem5_opt \
 *          src/sim/sc_main_cxx.cc src/sim/cxx_stats.cc \
 *          src/sim/sc_module.cc src/sim/sc_logger.cc
 */

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <systemc>

#include "base/statistics.hh"
#include "base/str.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "sc_logger.hh"
#include "sc_module.hh"
#include "sim/cxx_config_ini.hh"
#include "sim/cxx_manager.hh"
#include "sim/init_signals.hh"
#include "sim/serialize.hh"
#include "sim/simulate.hh"
#include "sim/stat_control.hh"
#include "sim/system.hh"
#include "stats.hh"

// Defining global string variable decalred in stats.hh
std::string filename;

void
usage(const std::string &prog_name)
{
    std::cerr << "Usage: " << prog_name << (
        " <config_file.ini> [ <option> ]\n\n"
        "OPTIONS:\n"
        "    -p <object> <param> <value>  -- set a parameter\n"
        "    -v <object> <param> <values> -- set a vector parameter from"
        " a comma\n"
        "                                    separated values string\n"
        "    -d <flag>                    -- set a debug flag (-<flag>\n"
        "                                    clear a flag)\n"
        "    -s <dir> <ticks>             -- save checkpoint to dir after"
        " the given\n"
        "                                    number of ticks\n"
        "    -r <dir>                     -- restore checkpoint to dir\n"
        "    -c <from> <to> <ticks>       -- switch from cpu 'from' to cpu"
        " 'to' after\n"
        "                                    the given number of ticks\n"
        "    -n <#cpus>                      the number of cpus to switch\n"
        "                                    (appended to 'to' and 'from'"
        " cpus above)\n"
        "\n"
        );

    std::exit(EXIT_FAILURE);
}

class SimControl : public Gem5SystemC::Module
{
  protected:
    int argc;
    char **argv;
    CxxConfigManager *config_manager;
    Gem5SystemC::Logger logger;

    bool checkpoint_restore;
    bool checkpoint_save;
    bool switch_cpus;
    std::string checkpoint_dir;
    std::string from_cpu;
    std::string to_cpu;
    Tick pre_run_time;
    Tick pre_switch_time;
    unsigned num_switch_cpus;

  public:
    SC_HAS_PROCESS(SimControl);

    SimControl(sc_core::sc_module_name name, int argc_, char **argv_);

    void run();
  private:
    /**
     * Switch a single CPU
     *
     * If numTotalCpus is greater than 1, the CPU index will be appended to
     * the object name when searching config manager for the CPU name
     *
     * @param The CPU number to switch
     * @param The total number of CPUs in the system
     */
    void switchCpu(unsigned cpuNum, unsigned numTotalCpus);

};

SimControl::SimControl(sc_core::sc_module_name name,
    int argc_, char **argv_) :
    Gem5SystemC::Module(name),
    argc(argc_),
    argv(argv_)
{
    SC_THREAD(run);

    std::string prog_name(argv[0]);
    unsigned int arg_ptr = 1;

    if (argc == 1)
        usage(prog_name);

    cxxConfigInit();

    /* Pass DPRINTF messages to SystemC */
    Trace::setDebugLogger(&logger);

    /* @todo need this as an option */
    Gem5SystemC::setTickFrequency();

    /* Make a SystemC-synchronising event queue and install it as the
     *  sole top level gem5 EventQueue */
    Gem5SystemC::Module::setupEventQueues(*this);

    if (sc_core::sc_get_time_resolution() !=
        sc_core::sc_time(1, sc_core::SC_PS))
    {
        fatal("Time resolution must be set to 1 ps for gem5 to work");
    }

    /* Enable keyboard interrupt, async I/O etc. */
    initSignals();

    /* Enable stats */
    Stats::initSimStats();
    Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);

    Trace::enable();
    setDebugFlag("Terminal");

    checkpoint_restore = false;
    checkpoint_save = false;
    switch_cpus = false;
    checkpoint_dir = "";
    from_cpu = "";
    to_cpu = "";
    pre_run_time = 1000000;
    pre_switch_time = 1000000;
    num_switch_cpus = 1;

    const std::string config_file(argv[arg_ptr]);

    CxxConfigFileBase *conf = new CxxIniFile();

    if (!conf->load(config_file.c_str()))
        fatal("Can't open config file: %s", config_file);

    arg_ptr++;

    config_manager = new CxxConfigManager(*conf);

    try {
        while (arg_ptr < argc) {
            std::string option(argv[arg_ptr]);
            arg_ptr++;
            unsigned num_args = argc - arg_ptr;

            if (option == "-p") {
                if (num_args < 3)
                    usage(prog_name);
                config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1],
                    argv[arg_ptr + 2]);
                arg_ptr += 3;
            } else if (option == "-v") {
                std::vector<std::string> values;

                if (num_args < 3)
                    usage(prog_name);
                tokenize(values, argv[2], ',');
                config_manager->setParamVector(argv[arg_ptr],
                    argv[arg_ptr], values);
                arg_ptr += 3;
            } else if (option == "-d") {
                if (num_args < 1)
                    usage(prog_name);
                if (argv[arg_ptr][0] == '-')
                    clearDebugFlag(argv[arg_ptr] + 1);
                else
                    setDebugFlag(argv[arg_ptr]);
                arg_ptr++;
            } else if (option == "-r") {
                if (num_args < 1)
                    usage(prog_name);
                checkpoint_dir = argv[arg_ptr];
                checkpoint_restore = true;
                arg_ptr++;
            } else if (option == "-s") {
                if (num_args < 2)
                    usage(prog_name);
                checkpoint_dir = argv[arg_ptr];
                std::istringstream(argv[arg_ptr + 1]) >> pre_run_time;
                checkpoint_save = true;
                arg_ptr += 2;
            } else if (option == "-c") {
                if (num_args < 3)
                    usage(prog_name);
                switch_cpus = true;
                from_cpu = argv[arg_ptr];
                to_cpu = argv[arg_ptr + 1];
                std::istringstream(argv[arg_ptr + 2]) >> pre_switch_time;
                arg_ptr += 3;
            } else if (option == "-n") {
                if (num_args < 1)
                    usage(prog_name);
                std::istringstream(argv[arg_ptr]) >> num_switch_cpus;
                arg_ptr++;
            } else {
                usage(prog_name);
            }
        }
    } catch (CxxConfigManager::Exception &e) {
        fatal("Config problem in sim object %s: %s", e.name, e.message);
    }

    if (checkpoint_save && checkpoint_restore) {
        fatal("Don't try to save and restore a checkpoint in the same"
                "run");
    }

    CxxConfig::statsEnable();
    getEventQueue(0)->dump();

    try {
        config_manager->instantiate();
    } catch (CxxConfigManager::Exception &e) {
        fatal("Config problem in sim object %s: %s", e.name, e.message);
    }
}

void SimControl::run()
{
    EventQueue *eventq = getEventQueue(0);
    GlobalSimLoopExitEvent *exit_event = NULL;

    /* There *must* be no scheduled events yet */
    fatal_if(!eventq->empty(), "There must be no posted events"
        " before SimControl::run");

    try {
        if (checkpoint_restore) {
            std::cerr << "Restoring checkpoint\n";

            CheckpointIn *checkpoint = new CheckpointIn(checkpoint_dir,
                config_manager->getSimObjectResolver());

            /* Catch SystemC up with gem5 after checkpoint restore.
             *  Note that gem5 leading SystemC is always a violation of the
             *  required relationship between the two, hence this careful
             *  catchup */

            DrainManager::instance().preCheckpointRestore();
            Serializable::unserializeGlobals(*checkpoint);

            Tick systemc_time = sc_core::sc_time_stamp().value();
            if (curTick() > systemc_time) {
                Tick wait_period = curTick() - systemc_time;

                std::cerr << "Waiting for " << wait_period << "ps for"
                    " SystemC to catch up to gem5\n";
                wait(sc_core::sc_time::from_value(wait_period));
            }

            config_manager->loadState(*checkpoint);
            config_manager->startup();
            config_manager->drainResume();

            std::cerr << "Restored from Checkpoint\n";
        } else {
            config_manager->initState();
            config_manager->startup();
        }
    } catch (CxxConfigManager::Exception &e) {
        fatal("Config problem in sim object %s: %s", e.name, e.message);
    }

    fatal_if(eventq->empty(), "No events to process after system startup");

    if (checkpoint_save) {
        exit_event = simulate(pre_run_time);

        unsigned int drain_count = 1;
        do {
            drain_count = config_manager->drain();

            std::cerr << "Draining " << drain_count << '\n';

            if (drain_count > 0) {
                exit_event = simulate();
            }
        } while (drain_count > 0);

        std::cerr << "Simulation stop at tick " << curTick()
            << ", cause: " << exit_event->getCause() << '\n';

        std::cerr << "Checkpointing\n";

        /* FIXME, this should really be serialising just for
         *  config_manager rather than using serializeAll's ugly
         *  SimObject static object list */
        Serializable::serializeAll(checkpoint_dir);

        std::cerr << "Completed checkpoint\n";

        config_manager->drainResume();
    }

    if (switch_cpus) {
        exit_event = simulate(pre_switch_time);

        unsigned int drain_count = 1;
        do {
            drain_count = config_manager->drain();

            std::cerr << "Draining " << drain_count << '\n';

            if (drain_count > 0) {
                exit_event = simulate();
            }
        } while (drain_count > 0);

        for (unsigned cpu_num = 0; cpu_num < num_switch_cpus; ++cpu_num) {
            switchCpu(cpu_num, num_switch_cpus);
        }

        config_manager->drainResume();

    }

    exit_event = simulate();

    std::cerr << "Exit at tick " << curTick()
        << ", cause: " << exit_event->getCause() << '\n';

    getEventQueue(0)->dump();

#if TRY_CLEAN_DELETE
    config_manager->deleteObjects();
#endif
}

int
sc_main(int argc, char **argv)
{
    SimControl sim_control("gem5", argc, argv);

    filename = "m5out/stats-systemc.txt";

    sc_core::sc_start();

    CxxConfig::statsDump();

    return EXIT_SUCCESS;
}

void
SimControl::switchCpu(unsigned cpuNum, unsigned numTotalCpus) {
    assert(cpuNum < numTotalCpus);
    std::ostringstream from_cpu_name;
    std::ostringstream to_cpu_name;

    from_cpu_name << from_cpu;
    to_cpu_name << to_cpu;

    if (numTotalCpus > 1) {
        from_cpu_name << cpuNum;
        to_cpu_name << cpuNum;
    }

    std::cerr << "Switching CPU "<< cpuNum << "(from='" << from_cpu_name.str()
        <<"' to '"<< to_cpu_name.str() << "')\n";

    /* Assume the system is called system */
    System &system = config_manager->getObject<System>("system");
    BaseCPU &old_cpu = config_manager->getObject<BaseCPU>(from_cpu_name.str());
    BaseCPU &new_cpu = config_manager->getObject<BaseCPU>(to_cpu_name.str());

    old_cpu.switchOut();

    // I'm not sure if this can be called before old_cpu.switchOut(). If so,
    // it is best to just move this call before the switchCpu loop in run()
    // where it previously was
    if (cpuNum == 0)
        system.setMemoryMode(Enums::timing);

    new_cpu.takeOverFrom(&old_cpu);


    std::cerr << "Switched CPU"<<cpuNum<<"\n";
}
