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

#ifndef __BUILDER_HH__
#define __BUILDER_HH__

#include <iosfwd>
#include <list>
#include <map>
#include <vector>

#include "sim/param.hh"

class SimObject;

//
// A SimObjectBuilder serves as an evaluation context for a set of
// parameters that describe a specific instance of a SimObject.  This
// evaluation context corresponds to a section in the .ini file (as
// with the base ParamContext) plus an optional node in the
// configuration hierarchy (the configNode member) for resolving
// SimObject references.  SimObjectBuilder is an abstract superclass;
// derived classes specialize the class for particular subclasses of
// SimObject (e.g., BaseCache).
//
// For typical usage, see the definition of
// SimObjectClass::createObject().
//
class SimObjectBuilder : public ParamContext
{
  private:
    // The corresponding node in the configuration hierarchy.
    // (optional: may be null if the created object is not in the
    // hierarchy)
    ConfigNode *configNode;

  public:
    SimObjectBuilder(ConfigNode *_configNode);

    virtual ~SimObjectBuilder();

    // call parse() on all params in this context to convert string
    // representations to parameter values
    virtual void parseParams(IniFile &iniFile);

    // parameter error prolog (override of ParamContext)
    virtual void printErrorProlog(std::ostream &);

    // generate the name for this SimObject instance (derived from the
    // configuration hierarchy node label and position)
    virtual const std::string &getInstanceName() { return iniSection; }

    // return the configuration hierarchy node for this context.
    virtual ConfigNode *getConfigNode() { return configNode; }

    // Create the actual SimObject corresponding to the parameter
    // values in this context.  This function is overridden in derived
    // classes to call a specific constructor for a particular
    // subclass of SimObject.
    virtual SimObject *create() = 0;
};


//
// Handy macros for initializing parameter members of classes derived
// from SimObjectBuilder.  Assumes that the name of the parameter
// member object is the same as the textual parameter name seen by the
// user.  (Note that '#p' is expanded by the preprocessor to '"p"'.)
//
#define INIT_PARAM(p, desc)		p(this, #p, desc)
#define INIT_PARAM_DFLT(p, desc, dflt)	p(this, #p, desc, dflt)

//
// Initialize an enumeration variable... assumes that 'map' is the
// name of an array of mappings (char * for SimpleEnumParam, or
// EnumParamMap for MappedEnumParam).
//
#define INIT_ENUM_PARAM(p, desc, map)	\
        p(this, #p, desc, map, sizeof(map)/sizeof(map[0]))
#define INIT_ENUM_PARAM_DFLT(p, desc, map, dflt)	\
        p(this, #p, desc, map, sizeof(map)/sizeof(map[0]), dflt)

//
// An instance of SimObjectClass corresponds to a class derived from
// SimObject.  The SimObjectClass instance serves to bind the string
// name (found in the config file) to a function that creates an
// instance of the appropriate derived class.
//
// This would be much cleaner in Smalltalk or Objective-C, where types
// are first-class objects themselves.
//
class SimObjectClass
{
  public:
    // Type CreateFunc is a pointer to a function that creates a new
    // simulation object builder based on a .ini-file parameter
    // section (specified by the first string argument), a unique name
    // for the object (specified by the second string argument), and
    // an optional config hierarchy node (specified by the third
    // argument).  A pointer to the new SimObjectBuilder is returned.
    typedef SimObjectBuilder *(*CreateFunc)(ConfigNode *configNode);

    static std::map<std::string,CreateFunc> *classMap;

    // Constructor.  For example:
    //
    // SimObjectClass baseCacheClass("BaseCache", newBaseCacheBuilder);
    //
    SimObjectClass(const std::string &className, CreateFunc createFunc);

    // create SimObject given name of class and pointer to
    // configuration hierarchy node
    static SimObject *createObject(IniFile &configDB, ConfigNode *configNode);

    // print descriptions of all parameters registered with all
    // SimObject classes
    static void describeAllClasses(std::ostream &os);
};

//
// Macros to encapsulate the magic of declaring & defining
// SimObjectBuilder and SimObjectClass objects
//

#define BEGIN_DECLARE_SIM_OBJECT_PARAMS(OBJ_CLASS)		\
class OBJ_CLASS##Builder : public SimObjectBuilder		\
{								\
  public:

#define END_DECLARE_SIM_OBJECT_PARAMS(OBJ_CLASS)		\
                                                                \
    OBJ_CLASS##Builder(ConfigNode *configNode);			\
    virtual ~OBJ_CLASS##Builder() {}				\
                                                                \
    OBJ_CLASS *create();					\
};

#define BEGIN_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS)			\
OBJ_CLASS##Builder::OBJ_CLASS##Builder(ConfigNode *configNode)	\
    : SimObjectBuilder(configNode),


#define END_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS)			\
{								\
}

#define CREATE_SIM_OBJECT(OBJ_CLASS)				\
OBJ_CLASS *OBJ_CLASS##Builder::create()

#define REGISTER_SIM_OBJECT(CLASS_NAME, OBJ_CLASS)		\
SimObjectBuilder *						\
new##OBJ_CLASS##Builder(ConfigNode *configNode)			\
{								\
    return new OBJ_CLASS##Builder(configNode);			\
}								\
                                                                \
SimObjectClass the##OBJ_CLASS##Class(CLASS_NAME,		\
                                     new##OBJ_CLASS##Builder);	\
                                                                \
/* see param.hh */						\
DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS)


#endif // __BUILDER_HH__
