/*
 * 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
 *
 *  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 *requestorObject, const std::string &requestPort,
        PortID requestPortIndex, SimObject *responderObject,
        const std::string &responsePort, PortID responsePortIndex);

    /** Bind a single (possibly vectored) request port to peers from the
     *  unparsed list peers with elements in the .ini connection format:
     *  path(.path)*.port[index] */
    void bindRequestPort(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__
