/*
 * Copyright (c) 2002-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 __SIM_PARAM_HH__
#define __SIM_PARAM_HH__

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

#include "sim/configfile.hh"
#include "sim/startup.hh"

// forward decls
class BaseParam;
class SimObject;

//
// The context of a parameter definition... usually a subclass of
// SimObjectBuilder (which derives from ParamContext), but abstracted
// here to support more global simulator control parameters as well.
//
class ParamContext : protected StartupCallback
{
  private:

    // static list of all ParamContext objects, built as a side effect
    // of the ParamContext constructor
    static std::list<ParamContext *> *ctxList;

  protected:

    // .ini file (database) for parameter lookup... initialized on call
    // to parseParams()
    IniFile *iniFilePtr;

    // .ini file section for parameter lookup
    const std::string iniSection;

    typedef std::vector<BaseParam *> ParamList;

    // list of parameters defined in this context
    ParamList *paramList;

    ParamList *getParamList() {
        if (!paramList)
            paramList = new ParamList;
        return paramList;
    }

  public:

    /// Initialization phases for ParamContext objects.
    enum InitPhase {
        NoAutoInit = -1,	///< Don't initialize at all... params
                                /// will be parsed later (used by
                                /// SimObjectBuilder, which parses
                                /// params in SimObject::create().
        OutputInitPhase = 0,	///< Output stream initialization
        TraceInitPhase = 1,	///< Trace context initialization:
                                /// depends on output streams, but
                                /// needs to come before others so we
                                /// can use tracing in other
                                /// ParamContext init code
        StatsInitPhase = 2,	///< Stats output initialization
        DefaultInitPhase = 3	///< Everything else
    };

    /// Records the initialization phase for this ParamContext.
    InitPhase initPhase;

    /// Constructor.
    /// @param _iniSection Name of .ini section corresponding to this context.
    /// @param _initPhase Initialization phase  (see InitPhase).
    ParamContext(const std::string &_iniSection,
                 InitPhase _initPhase = DefaultInitPhase);

    virtual ~ParamContext() {}

    // add a parameter to the context... called from the parameter
    // object's constructor (see BaseParam::BaseParam())
    void addParam(BaseParam *);

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

    // Check parameter values for validity & consistency. Default
    // implementation is no-op; derive subclass & override to add
    // actual functionality here
    virtual void checkParams();

    // Clean up at end of execution: close file descriptors, etc.
    // Default implementation is no-op; derive subclass & override to
    // add actual functionality here
    virtual void cleanup();

    // dump parameter descriptions
    void describeParams(std::ostream &);

    // Display the parameters & values used
    void showParams(std::ostream &);

    // print context information for parameter error
    virtual void printErrorProlog(std::ostream &);

    // resolve a SimObject name in this context to an object pointer.
    virtual SimObject *resolveSimObject(const std::string &name);

    // generate the name for this instance of this context (used as a
    // prefix to create unique names in resolveSimObject()
    virtual const std::string &getInstanceName() { return iniSection; }

    // return the configuration hierarchy node for this context.  Bare
    // ParamContext objects have no corresponding node, so the default
    // implementation returns NULL.
    virtual ConfigNode *getConfigNode() { return NULL; }

    // Parse all parameters registered with all ParamContext objects.
    static void parseAllContexts(IniFile &iniFile);

    // Check all parameters registered with all ParamContext objects.
    // (calls checkParams() on each)
    static void checkAllContexts();

    // Print all parameter values on indicated ostream.
    static void showAllContexts(std::ostream &os);

    // Clean up all registered ParamContext objects.  (calls cleanup()
    // on each)
    static void cleanupAllContexts();

    // print descriptions of all parameters registered with all
    // ParamContext objects
    static void describeAllContexts(std::ostream &os);
};


//
// Base class for all parameter objects
//
class BaseParam
{
  public:

    ParamContext *context;
    std::string name;
    std::string description;	// text description for help message
    bool wasSet;	// true if parameter was set by user
    bool hasDefault;	// true if parameter has default value

    BaseParam(ParamContext *_context, const std::string &_name,
              const std::string &_description, bool _hasDefault)
        : context(_context), name(_name), description(_description),
          wasSet(false), hasDefault(_hasDefault)
    {
        context->addParam(this);
    }

    virtual ~BaseParam() {}

    // a parameter is valid only if its value was set by the user or
    // it has a default value
    bool isValid() const
    {
        return (wasSet || hasDefault);
    }

    // set value by parsing string
    virtual void parse(const std::string &s) = 0;

    // display value to stream
    virtual void showValue(std::ostream &) const = 0;

    // display type to stream
    virtual void showType(std::ostream &) const = 0;

    // signal parse or usage error
    virtual void die(const std::string &err) const;
};

//
// Template classes to specialize parameters to specific types.
//
// Param<T> is for single-valued (scalar) parameters of type T.
// VectorParam<T> is for multi-valued (vector) parameters of type T.
// These are specified in the .ini file as a space-delimited list of
// arguments.
//
template <class T>
class Param : public BaseParam
{
  protected:

    T value;

  public:

    // Param with default value: set value to default
    Param(ParamContext *context,
          const std::string &name, const std::string &description, T dfltValue)
        : BaseParam(context, name, description, true),
          value(dfltValue)
    {
    }

    // Param with no default value: leave value uninitialized
    Param(ParamContext *context,
          const std::string &name, const std::string &description)
        : BaseParam(context, name, description, false)
    {
    }

    virtual ~Param() {}

    operator T&()
    {
        // if we attempt to reference an invalid parameter (i.e., one
        // with no default value that was not set by the user), die.
        if (!isValid())
            die("not found");
        return value;
    }

    // display value to stream
    virtual void showValue(std::ostream &os) const;

    // display type to stream
    virtual void showType(std::ostream &) const;

    // set value by parsing string
    virtual void parse(const std::string &s);
};


//
// Template class for vector-valued parameters (lists)
//
template <class T>
class VectorParam : public BaseParam
{
  protected:

    std::vector<T> value;

  public:

    typedef typename std::vector<T>::size_type size_type;

    // Param with default value: set value to default
    VectorParam(ParamContext *context, const std::string &name,
                const std::string &description,
                const std::vector<T> &dfltValue)
        : BaseParam(context, name, description, true),
          value(dfltValue)
    {
    }

    // Param with no default value: leave value uninitialized
    VectorParam(ParamContext *context,
                const std::string &name, const std::string &description)
        : BaseParam(context, name, description, false)
    {
    }

    virtual ~VectorParam() {}

    // basic vector access methods
    size_type size() const
    {
        if (!isValid())
            die("not found");
        return value.size();
    }

    const T &operator[](size_type n) const
    {
        if (!isValid())
            die("not found");
        return value[n];
    }

    // return reference to value vector
    operator std::vector<T>&()
    {
        if (!isValid())
            die("not found");
        return value;
    }

    // display value to stream
    virtual void showValue(std::ostream &os) const;

    // display type to stream
    virtual void showType(std::ostream &) const;

    // set value by parsing string
    virtual void parse(const std::string &s);
};

//
// Specialization of Param<int> and VectorParam<int> to handle
// enumerated types is done in two ways, using SimpleEnumParam and
// MappedEnumParam (and their vector counterparts,
// SimpleEnumVectorParam and MappedEnumVectorParam).  SimpleEnumParam
// takes an array of strings and maps them to integers based on array
// index.  MappedEnumParam takes an array of string-to-int mappings,
// allowing for mapping strings to non-contiguous integer values, or
// mapping multiple strings to the same integer value.
//
// Both SimpleEnumParam and MappedEnumParam are implemented using a
// single template class, EnumParam<Map>, which takes the type of the map
// as a parameter (const char * or EnumParamMap).  Similarly,
// SimpleEnumVectorParam and MappedEnumVectorParam are both
// implemented using EnumVectorParam<Map>.
//
template <class Map>
class EnumParam : public Param<int>
{
    const int num_values;
    const Map *map;

  public:

    // Param with default value: set value to default
    EnumParam(ParamContext *context,
              const std::string &name, const std::string &description,
              const Map *_map, int _num_values,
              int dfltValue)
        : Param<int>(context, name, description, dfltValue),
          num_values(_num_values), map(_map)
    {
    }

    // Param with no default value: leave value uninitialized
    EnumParam(ParamContext *context,
              const std::string &name, const std::string &description,
              const Map *_map, int _num_values)
        : Param<int>(context, name, description),
          num_values(_num_values), map(_map)
    {
    }

    virtual ~EnumParam() {}

    // display value to stream
    virtual void showValue(std::ostream &os) const;

    // display type to stream
    virtual void showType(std::ostream &) const;

    // set value by parsing string
    virtual void parse(const std::string &s);
};

//
// Vector counterpart to SimpleEnumParam
//
template <class Map>
class EnumVectorParam : public VectorParam<int>
{
    const int num_values;
    const Map *map;

  public:

    // Param with default value: set value to default
    EnumVectorParam(ParamContext *context,
                    const std::string &name, const std::string &description,
                    const Map *_map, int _num_values,
                    std::vector<int> &dfltValue)
        : VectorParam<int>(context, name, description, dfltValue),
          num_values(_num_values), map(_map)
    {
    }

    // Param with no default value: leave value uninitialized
    EnumVectorParam(ParamContext *context,
                    const std::string &name, const std::string &description,
                    const Map *_map, int _num_values)
        : VectorParam<int>(context, name, description),
          num_values(_num_values), map(_map)
    {
    }

    virtual ~EnumVectorParam() {}

    // display value to stream
    virtual void showValue(std::ostream &os) const;

    // display type to stream
    virtual void showType(std::ostream &) const;

    // set value by parsing string
    virtual void parse(const std::string &s);
};

// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)

template <class ENUM>
class SimpleEnumParam : public EnumParam<const char *>
{
  public:

    SimpleEnumParam(ParamContext *context,
                    const std::string &name, const std::string &description,
                    const char **_map, int _num_values,
                    ENUM dfltValue)
        : EnumParam<const char *>(context, name, description,
                                  _map, _num_values, (int)dfltValue)
    {
    }

    SimpleEnumParam(ParamContext *context,
                    const std::string &name, const std::string &description,
                    const char **_map, int _num_values)
        : EnumParam<const char *>(context, name, description,
                                  _map, _num_values)
    {
    }

    operator ENUM() const
    {
        if (!isValid())
            die("not found");
        return (ENUM)value;
    }
};


// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)

template <class ENUM>
class SimpleEnumVectorParam : public EnumVectorParam<const char *>
{
  public:

    // skip default value constructor: too much pain to convert
    // vector<ENUM> initializer to vector<int>


    SimpleEnumVectorParam(ParamContext *context,
                          const std::string &name,
                          const std::string &description,
                          const char **_map, int _num_values)
        : EnumVectorParam<const char *>(context, name, description,
                                        _map, _num_values)
    {
    }

    ENUM operator[](size_type n)
    {
        if (!isValid())
            die("not found");
        return (ENUM)value[n];
    }
};


//
// Handle enums via string-to-int map (see comment above).
//

// An array of string-to-int mappings must be supplied using the
// following type.
typedef struct {
    const char *name;
    int value;
} EnumParamMap;

// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)

template <class ENUM>
class MappedEnumParam : public EnumParam<EnumParamMap>
{
  public:

    MappedEnumParam(ParamContext *context,
                    const std::string &name, const std::string &description,
                    const EnumParamMap *_map, int _num_values,
                    ENUM dfltValue)
        : EnumParam<EnumParamMap>(context, name, description,
                                  _map, _num_values, (int)dfltValue)
    {
    }

    MappedEnumParam(ParamContext *context,
                    const std::string &name, const std::string &description,
                    const EnumParamMap *_map, int _num_values)
        : EnumParam<EnumParamMap>(context, name, description,
                                  _map, _num_values)
    {
    }

    operator ENUM()
    {
        if (!isValid())
            die("not found");
        return (ENUM)value[this->n];
    }
};


// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)

template <class ENUM>
class MappedEnumVectorParam : public EnumVectorParam<EnumParamMap>
{
  public:

    // skip default value constructor: too much pain to convert
    // vector<ENUM> initializer to vector<int>


    MappedEnumVectorParam(ParamContext *context,
                          const std::string &name,
                          const std::string &description,
                          const EnumParamMap *_map, int _num_values)
        : EnumVectorParam<EnumParamMap>(context, name, description,
                                        _map, _num_values)
    {
    }

    ENUM operator[](size_type n)
    {
        if (!isValid())
            die("not found");
        return (ENUM)value[n];
    }
};


//
// Parameters that point to other simulation objects (e.g. caches,
// busses, etc.) are handled by specializing SimObjectBaseParam to the
// specific subtype.  The main purpose of SimObjectBaseParam is to
// provide a place to stick several helper functions common to all
// SimObject-derived parameters.
//
class SimObjectBaseParam : public BaseParam
{
  public:

    SimObjectBaseParam(ParamContext *context, const std::string &name,
                       const std::string &description, bool hasDefault)
        : BaseParam(context, name, description, hasDefault)
    {
    }

    virtual ~SimObjectBaseParam() {}

    // helper function for SimObjectParam<T>::showValue()
    void showValue(std::ostream &os, SimObject *obj) const;

    // helper function for SimObjectParam<T>::parse()
    void parse(const std::string &s, SimObject *&value);

    // helper function for SimObjectParam<T>::parse()
    void parse(const std::string &s, std::vector<SimObject *>&value_vec);
};


//
// Parameter to a specific type of SimObject.  Note that T must be a
// pointer to a class derived from SimObject (e.g., <CPU *>).
//

template <class T> class SimObjectParam;

template <class T>
class SimObjectParam<T *> : public SimObjectBaseParam
{
  protected:

    T *value;

  public:

    // initialization w/o default
    SimObjectParam(ParamContext *context,
                   const std::string &name, const std::string &description)
        : SimObjectBaseParam(context, name, description, false)
    {
    }

    // initialization wit=h default
    SimObjectParam(ParamContext *context,
                   const std::string &name, const std::string &description,
                   T *dfltValue)
        : SimObjectBaseParam(context, name, description, true),
          value(dfltValue)
    {
    }

    virtual ~SimObjectParam() {}

    // convert to pointer
    operator T*()
    {
        if (!isValid())
            die("not found");
        return value;
    }

    T *operator->() const
    {
        if (!isValid())
            die("not found");
        return value;
    }

    // display value to stream
    virtual void showValue(std::ostream &os) const
    {
        SimObjectBaseParam::showValue(os, value);
    }

    // display type to stream: see REGISTER_SIM_OBJECT macro in
    // sim_object.hh for declaration
    virtual void showType(std::ostream &os) const;

    // set value by parsing string
    virtual void parse(const std::string &s)
    {
        SimObject *so_ptr;
        // first parse to generic SimObject *
        SimObjectBaseParam::parse(s, so_ptr);
        // now dynamic_cast to specific derived type
        value = dynamic_cast<T *>(so_ptr);
        // check for failure of dynamic_cast
        if (value == NULL && so_ptr != NULL)
            die("not of appropriate type");
    }
};


//
// Vector counterpart to SimObjectParam<T>
//

template <class T> class SimObjectVectorParam;

template <class T>
class SimObjectVectorParam<T *> : public SimObjectBaseParam
{
  protected:

    std::vector<T *> value;

  public:

    typedef typename std::vector<T *>::size_type size_type;

    SimObjectVectorParam(ParamContext *context,
                         const std::string &name,
                         const std::string &description)
        : SimObjectBaseParam(context, name, description, false)
    {
    }

    SimObjectVectorParam(ParamContext *context,
                         const std::string &name,
                         const std::string &description,
                         std::vector<T *> dfltValue)
        : SimObjectBaseParam(context, name, description, true),
          value(dfltValue)
    {
    }

    virtual ~SimObjectVectorParam() {}

    // basic vector access methods
    size_type size() const
    {
        if (!isValid())
            die("not found");
        return value.size();
    }

    T *&operator[](size_type n)
    {
        if (!isValid())
            die("not found");
        return value[n];
    }

    // return reference to value vector
    operator std::vector<T *>&()
    {
        if (!isValid())
            die("not found");
        return value;
    }

    // display value to stream
    virtual void showValue(std::ostream &os) const
    {
        for (int i = 0; i < value.size(); i++) {
            if (i != 0)
                os << " ";
            SimObjectBaseParam::showValue(os, value[i]);
        }
    }

    // display type to stream: see
    virtual void showType(std::ostream &os) const;

    // set value by parsing string
    virtual void parse(const std::string &s)
    {
        std::vector<SimObject *> so_ptr_vec;
        // first parse to generic SimObject * vector (from SimObjectBaseParam)
        SimObjectBaseParam::parse(s, so_ptr_vec);

        value.resize(so_ptr_vec.size());

        for (int i = 0; i < so_ptr_vec.size(); ++i) {
            // now dynamic_cast to specific derived type
            value[i] = dynamic_cast<T *>(so_ptr_vec[i]);
            // check for failure of dynamic_cast
            if (value[i] == NULL && so_ptr_vec[i] != NULL)
                die("not of appropriate type");
        }
    }
};

//
// Macro to define showType() methods for SimObjectParam &
// SimObjectVectorParam.  Can't do this automatically as it requires a
// string name for the type, which you can't get from a template
// argument.  For concrete derived SimObject types, this macro is
// automatically invoked by REGISTER_SIM_OBJECT() (see sim_object.hh).
//
#define DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS)		\
template<>								\
void									\
SimObjectParam<OBJ_CLASS *>::showType(std::ostream &os)	const		\
{									\
    os << CLASS_NAME;							\
}									\
                                                                        \
template<>								\
void									\
SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const	\
{									\
    os << "vector of " << CLASS_NAME;					\
}


//
// Declarations for low-level parsing & displaying functions.  These
// are used internally, but should not be used directly by clients of
// the parameter mechanism, but are declared here so they can be
// shared with the serialization code (see sim/serialize.cc).
template <class T> bool parseParam(const std::string &str, T &data);
template <class T> void showParam(std::ostream &os, const T &data);

#endif // _SIM_PARAM_HH_
