/*
 * 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.
 *
 * Authors: Andrew Bardsley
 */

/**
 * @file
 *
 *  C++-only configuration and instantiation support.  This allows a
 *  config to be read back from a config file and instantiated without
 *  Python.  Useful if you want to embed gem5 within a larger system
 *  without carrying the integration cost of the fully-featured
 *  configuration system.
 *
 *  This file contains the config loading/storing manager class
 */

#ifndef __SIM_CXX_MANAGER_HH__
#define __SIM_CXX_MANAGER_HH__

#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/cprintf.hh"
#include "sim/cxx_config.hh"

class CheckpointIn;

/** This class allows a config file to be read into gem5 (generating the
 *  appropriate SimObjects) from C++ */
class CxxConfigManager
{
  protected:
    /** Configuration file being read */
    CxxConfigFileBase &configFile;

    /** Flags to pass to affect param setting */
    CxxConfigParams::Flags flags;

  public:
    /** Exception for instantiate/post-instantiate errors */
    class Exception : public std::exception
    {
      public:
        std::string name;
        std::string message;

      public:
        Exception(const std::string &name_, const std::string &message_) :
            name(name_), message(message_)
        { }

        const char *what() const throw() { return message.c_str(); }

        ~Exception() throw() { }
    };

    /** Name substitution when instantiating any object whose name starts
     *  with fromPrefix.  Where both renamed and unrenamed names are used
     *  in the code, `object' as part of a name usually refers to the
     *  unrenamed name (the name as it appears in the config file) and
     *  `instance' is part of the renamed name */
    struct Renaming
    {
        std::string fromPrefix;
        std::string toPrefix;

        Renaming(const std::string &from_prefix,
            const std::string &to_prefix) :
            fromPrefix(from_prefix),
            toPrefix(to_prefix)
        { }
    };

  public:
    /** SimObject indexed by name */
    std::map<std::string, SimObject *> objectsByName;

    /** ...Params objects created by this manager */
    std::map<std::string, CxxConfigParams *> objectParamsByName;

    /** SimObjects in order.  This is populated by findAllObjects */
    std::list<SimObject *> objectsInOrder;

  protected:
    /** While configuring, inVisit contains names of SimObjects visited in
     *  this recursive configuration walk */
    std::set<std::string> inVisit;

    /** All the renamings applicable when instantiating objects */
    std::list<Renaming> renamings;

    /** Bind a single connection between two objects' ports */
    void bindPort(SimObject *masterObject, const std::string &masterPort,
        PortID masterPortIndex, SimObject *slaveObject,
        const std::string &slavePort, PortID slavePortIndex);

    /** Bind a single (possibly vectored) master port to peers from the
     *  unparsed list peers with elements in the .ini connection format:
     *  path(.path)*.port[index] */
    void bindMasterPort(SimObject *object,
        const CxxConfigDirectoryEntry::PortDesc &port,
        const std::vector<std::string> &peers);

    /** Apply the first matching renaming in renamings to the given name */
    std::string rename(const std::string &from_name);

    /** Apply the first matching renaming in reverse (toPrefix -> fromPrefix
     *  for the given name */
    std::string unRename(const std::string &to_name);

  protected:
    /** Bind the ports of all the objects in objectInOrder order.
     *  Also */
    void bindAllPorts();

    /** Class for resolving SimObject names to SimObjects usable by the
     *  checkpoint restore mechanism */
    class SimObjectResolver : public ::SimObjectResolver
    {
      protected:
        CxxConfigManager &configManager;

      public:
        SimObjectResolver(CxxConfigManager &configManager_) :
            configManager(configManager_)
        { }

        SimObject *resolveSimObject(const std::string &name)
        { return &(configManager.getObject<SimObject>(name)); }
    };

    /** Singleton instance of SimObjectResolver */
    SimObjectResolver simObjectResolver;

  public:
    CxxConfigManager(CxxConfigFileBase &configFile_);

    /** Find the type field for a named object and return both the
     *  name of the type to object_type and the object's directory
     *  entry as the return value */
    const CxxConfigDirectoryEntry &findObjectType(
        const std::string &object_name, std::string &object_type);

    /** Add a name prefix renaming to those currently applied.  Call this
     *  before trying to instantiate any object as the name mappings are
     *  not applied to the config tree read from the config file but are
     *  applied while processing instantiations */
    void addRenaming(const Renaming &renaming);

  public:
    /** Bind the ports of a single SimObject */
    void bindObjectPorts(SimObject *object);

    /** Walk the configuration starting with object object_name and fill
     *  in all the elements of this object on the way.  This involves:
     *  <ul>
     *    <li>Calling findObjectParams to make the ...Params object
     *      If findObjectParams has already been called for this object,
     *      the ...Params object generated by that called (stored in
     *      (objectParamsByName[object_name] will be used)</li>
     *    <li>Populating the ...Params object references to other
     *      SimObjects by recursively descending into the trees formed
     *      by SimObject references</li>
     *    <li>Building the final SimObject and adding it to
     *      objectsByName</li>
     *    <li>If visit_children is true, recursively visit all this
     *      object's children and build/find them too</li>
     *  </ul>
     *  After the first call, this function will return
     *  objectsByName[object_name] */
    SimObject *findObject(const std::string &object_name,
        bool visit_children = false);

    /** Find the parameters for the named object.  Returns NULL if the
     *  object isn't in the configuration.  For the first call with a
     *  particular object name, a new CxxConfigParams descended object
     *  is made with the configuration file contents for this object.
     *  This involves populating that ...Params object with:
     *  <ul>
     *    <li>parameter values from the configuration file</li>
     *    <li>port connection connection counts from the connection counts
     *      indicated by the number of peer ports in the configuration
     *      file</li>
     *    <li>nulled (or vector<>::clear'ed) SimObject references for
     *      SimObject-values parameters</li>
     *  </ul>
     *  The ...Params object is then added to objectParamsByName
     *  After the first call, this function will return
     *  objectParamsByName[object_name] */
    CxxConfigParams *findObjectParams(const std::string &object_name);

    /** Populate objectsInOrder with a preorder, depth first traversal from
     *  the given object name down through all its children */
    void findTraversalOrder(const std::string &object_name);

    /** Find an object from objectsByName with a type-checking cast.
     *  This function is provided for manipulating objects after
     *  instantiate as it assumes the named object exists. */
    template<typename SimObjectType>
    SimObjectType &
    getObject(const std::string &object_name)
    {
        if (objectsByName.find(object_name) == objectsByName.end()) {
            throw Exception("", csprintf("No sim object named: %s",
                object_name));
        }

        SimObjectType *object = dynamic_cast<SimObjectType *>(
            objectsByName[object_name]);

        if (!object) {
            throw Exception("", csprintf("Sim object: %s  has the wrong"
                " type", object_name));
        }

        return *object;
    }

    /** Perform mem_func on each SimObject */
    void forEachObject(void (SimObject::*mem_func)());

    /** Find all objects by iterating over the object names in the config
     *  file with findObject.  Also populate the traversal order */
    void findAllObjects();

    /** Parse a port string of the form 'path(.path)*.port[index]' into
     *  path, port and index */
    static void parsePort(const std::string &inp,
        std::string &path, std::string &port, unsigned int &index);

    /** Build all objects (if build_all is true, otherwise objects must
     *  have been individually findObject-ed and added to the traversal
     *  order) and perform all the configuration specific actions up to,
     *  but not including initState.
     *
     *  If you want to set some parameters before completing instantiation,
     *  call findObjectParams on the objects you want to modify, then call
     *  instantiate */
    void instantiate(bool build_all = true);

    /** Call initState on all objects */
    void initState();

    /** Call startup on all objects */
    void startup();

    /** Drain all objects */
    unsigned int drain();

    /** Resume from drain */
    void drainResume();

    /** Serialize (checkpoint) all objects to the given stream */
    void serialize(std::ostream &os);

    /** Load all objects' state from the given Checkpoint */
    void loadState(CheckpointIn &checkpoint);

    /** Delete all objects and clear objectsByName and objectsByOrder */
    void deleteObjects();

    /** Get the resolver used to map SimObject names to SimObjects for
     *  checkpoint restore */
    SimObjectResolver &getSimObjectResolver() { return simObjectResolver; }

    /** Convenience functions for calling set... member functions on a
     *  CxxConfigParams for an object.  These functions throw Exception
     *  rather than return a bool on failure */
    void setParam(const std::string &object_name,
        const std::string &param_name, const std::string &param_value);
    void setParamVector(const std::string &object_name,
        const std::string &param_name,
        const std::vector<std::string> &param_values);
};

#endif // __SIM_CXX_MANAGER_HH__
