/*
 * Copyright (c) 2000-2005 The Regents of The University of Michigan
 * 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.
 */

///
/// @file sim/main.cc
///
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <libgen.h>
#include <stdlib.h>
#include <signal.h>

#include <list>
#include <string>
#include <vector>

#include "base/copyright.hh"
#include "base/embedfile.hh"
#include "base/inifile.hh"
#include "base/misc.hh"
#include "base/output.hh"
#include "base/pollevent.hh"
#include "base/statistics.hh"
#include "base/str.hh"
#include "base/time.hh"
#include "cpu/base.hh"
#include "cpu/smt.hh"
#include "python/pyconfig.hh"
#include "sim/async.hh"
#include "sim/builder.hh"
#include "sim/configfile.hh"
#include "sim/host.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
#include "sim/stat_control.hh"
#include "sim/stats.hh"
#include "sim/root.hh"

using namespace std;

// See async.h.
volatile bool async_event = false;
volatile bool async_dump = false;
volatile bool async_dumpreset = false;
volatile bool async_exit = false;
volatile bool async_io = false;
volatile bool async_alarm = false;

/// Stats signal handler.
void
dumpStatsHandler(int sigtype)
{
    async_event = true;
    async_dump = true;
}

void
dumprstStatsHandler(int sigtype)
{
    async_event = true;
    async_dumpreset = true;
}

/// Exit signal handler.
void
exitNowHandler(int sigtype)
{
    async_event = true;
    async_exit = true;
}

/// Abort signal handler.
void
abortHandler(int sigtype)
{
    cerr << "Program aborted at cycle " << curTick << endl;

#if TRACING_ON
    // dump trace buffer, if there is one
    Trace::theLog.dump(cerr);
#endif
}

/// Simulator executable name
char *myProgName = "";

/// Show brief help message.
void
showBriefHelp(ostream &out)
{
    char *prog = basename(myProgName);

    ccprintf(out, "Usage:\n");
    ccprintf(out,
"%s [-d <dir>] [-E <var>[=<val>]] [-I <dir>] [-P <python>]\n"
"        [--<var>=<val>] <config file>\n"
"\n"
"   -d            set the output directory to <dir>\n"
"   -E            set the environment variable <var> to <val> (or 'True')\n"
"   -I            add the directory <dir> to python's path\n"
"   -P            execute <python> directly in the configuration\n"
"   --var=val     set the python variable <var> to '<val>'\n"
"   <configfile>  config file name (ends in .py)\n\n",
             prog);

    ccprintf(out, "%s -X\n   -X            extract embedded files\n\n", prog);
    ccprintf(out, "%s -h\n   -h            print short help\n\n", prog);
}

/// Print welcome message.
void
sayHello(ostream &out)
{
    extern const char *compileDate;	// from date.cc

    ccprintf(out, "M5 Simulator System\n");
    // display copyright
    ccprintf(out, "%s\n", briefCopyright);
    ccprintf(out, "M5 compiled on %d\n", compileDate);

    char *host = getenv("HOSTNAME");
    if (!host)
        host = getenv("HOST");

    if (host)
        ccprintf(out, "M5 executing on %s\n", host);

    ccprintf(out, "M5 simulation started %s\n", Time::start);
}

///
/// Echo the command line for posterity in such a way that it can be
/// used to rerun the same simulation (given the same .ini files).
///
void
echoCommandLine(int argc, char **argv, ostream &out)
{
    out << "command line: " << argv[0];
    for (int i = 1; i < argc; i++) {
        string arg(argv[i]);

        out << ' ';

        // If the arg contains spaces, we need to quote it.
        // The rest of this is overkill to make it look purty.

        // print dashes first outside quotes
        int non_dash_pos = arg.find_first_not_of("-");
        out << arg.substr(0, non_dash_pos);	// print dashes
        string body = arg.substr(non_dash_pos);	// the rest

        // if it's an assignment, handle the lhs & rhs separately
        int eq_pos = body.find("=");
        if (eq_pos == string::npos) {
            out << quote(body);
        }
        else {
            string lhs(body.substr(0, eq_pos));
            string rhs(body.substr(eq_pos + 1));

            out << quote(lhs) << "=" << quote(rhs);
        }
    }
    out << endl << endl;
}

char *
getOptionString(int &index, int argc, char **argv)
{
    char *option = argv[index] + 2;
    if (*option != '\0')
        return option;

    // We didn't find an argument, it must be in the next variable.
    if (++index >= argc)
        panic("option string for option '%s' not found", argv[index - 1]);

    return argv[index];
}

int
main(int argc, char **argv)
{
    // Save off program name
    myProgName = argv[0];

    signal(SIGFPE, SIG_IGN);		// may occur on misspeculated paths
    signal(SIGTRAP, SIG_IGN);
    signal(SIGUSR1, dumpStatsHandler);		// dump intermediate stats
    signal(SIGUSR2, dumprstStatsHandler);	// dump and reset stats
    signal(SIGINT, exitNowHandler);		// dump final stats and exit
    signal(SIGABRT, abortHandler);

    bool configfile_found = false;
    PythonConfig pyconfig;
    string outdir;

    if (argc < 2) {
        showBriefHelp(cerr);
        exit(1);
    }

    sayHello(cerr);

    // Parse command-line options.
    // Since most of the complex options are handled through the
    // config database, we don't mess with getopts, and just parse
    // manually.
    for (int i = 1; i < argc; ++i) {
        char *arg_str = argv[i];

        // if arg starts with '--', parse as a special python option
        // of the format --<python var>=<string value>, if the arg
        // starts with '-', it should be a simulator option with a
        // format similar to getopt.  In any other case, treat the
        // option as a configuration file name and load it.
        if (arg_str[0] == '-' && arg_str[1] == '-') {
            string str = &arg_str[2];
            string var, val;

            if (!split_first(str, var, val, '='))
                panic("Could not parse configuration argument '%s'\n"
                      "Expecting --<variable>=<value>\n", arg_str);

            pyconfig.setVariable(var, val);
        } else if (arg_str[0] == '-') {
            char *option;
            string var, val;

            // switch on second char
            switch (arg_str[1]) {
              case 'd':
                outdir = getOptionString(i, argc, argv);
                break;

              case 'h':
                showBriefHelp(cerr);
                exit(1);

              case 'E':
                option = getOptionString(i, argc, argv);
                if (!split_first(option, var, val, '='))
                    val = "True";

                if (setenv(var.c_str(), val.c_str(), true) == -1)
                    panic("setenv: %s\n", strerror(errno));
                break;

              case 'I':
                option = getOptionString(i, argc, argv);
                pyconfig.addPath(option);
                break;

              case 'P':
                option = getOptionString(i, argc, argv);
                pyconfig.writeLine(option);
                break;

              case 'X': {
                  list<EmbedFile> lst;
                  EmbedMap::all(lst);
                  list<EmbedFile>::iterator i = lst.begin();
                  list<EmbedFile>::iterator end = lst.end();

                  while (i != end) {
                      cprintf("Embedded File: %s\n", i->name);
                      cout.write(i->data, i->length);
                      ++i;
                  }

                  return 0;
              }

              default:
                showBriefHelp(cerr);
                panic("invalid argument '%s'\n", arg_str);
            }
        } else {
            string file(arg_str);
            string base, ext;

            if (!split_last(file, base, ext, '.') || ext != "py")
                panic("Config file '%s' must end in '.py'\n", file);

            pyconfig.load(file);
            configfile_found = true;
        }
    }

    if (outdir.empty()) {
        char *env = getenv("OUTPUT_DIR");
        outdir = env ? env : ".";
    }

    simout.setDirectory(outdir);

    char *env = getenv("CONFIG_OUTPUT");
    if (!env)
        env = "config.out";
    configStream = simout.find(env);

    if (!configfile_found)
        panic("no configuration file specified!");

    // The configuration database is now complete; start processing it.
    IniFile inifile;
    if (!pyconfig.output(inifile))
        panic("Error processing python code");

    // Initialize statistics database
    Stats::InitSimStats();

    // Now process the configuration hierarchy and create the SimObjects.
    ConfigHierarchy configHierarchy(inifile);
    configHierarchy.build();
    configHierarchy.createSimObjects();

    // Parse and check all non-config-hierarchy parameters.
    ParamContext::parseAllContexts(inifile);
    ParamContext::checkAllContexts();

    // Print hello message to stats file if it's actually a file.  If
    // it's not (i.e. it's cout or cerr) then we already did it above.
    if (simout.isFile(*outputStream))
        sayHello(*outputStream);

    // Echo command line and all parameter settings to stats file as well.
    echoCommandLine(argc, argv, *outputStream);
    ParamContext::showAllContexts(*configStream);

    // Do a second pass to finish initializing the sim objects
    SimObject::initAll();

    // Restore checkpointed state, if any.
    configHierarchy.unserializeSimObjects();

    // Done processing the configuration database.
    // Check for unreferenced entries.
    if (inifile.printUnreferenced())
        panic("unreferenced sections/entries in the intermediate ini file");

    SimObject::regAllStats();

    // uncomment the following to get PC-based execution-time profile
#ifdef DO_PROFILE
    init_profile((char *)&_init, (char *)&_fini);
#endif

    // Check to make sure that the stats package is properly initialized
    Stats::check();

    // Reset to put the stats in a consistent state.
    Stats::reset();

    warn("Entering event queue.  Starting simulation...\n");
    SimStartup();
    while (!mainEventQueue.empty()) {
        assert(curTick <= mainEventQueue.nextTick() &&
               "event scheduled in the past");

        // forward current cycle to the time of the first event on the
        // queue
        curTick = mainEventQueue.nextTick();
        mainEventQueue.serviceOne();

        if (async_event) {
            async_event = false;
            if (async_dump) {
                async_dump = false;

                using namespace Stats;
                SetupEvent(Dump, curTick);
            }

            if (async_dumpreset) {
                async_dumpreset = false;

                using namespace Stats;
                SetupEvent(Dump | Reset, curTick);
            }

            if (async_exit) {
                async_exit = false;
                new SimExitEvent("User requested STOP");
            }

            if (async_io || async_alarm) {
                async_io = false;
                async_alarm = false;
                pollQueue.service();
            }
        }
    }

    // This should never happen... every conceivable way for the
    // simulation to terminate (hit max cycles/insts, signal,
    // simulated system halts/exits) generates an exit event, so we
    // should never run out of events on the queue.
    exitNow("no events on event loop!  All CPUs must be idle.", 1);

    return 0;
}
