/*
 * 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.
 *
 * Authors: Nathan Binkert
 *          Erik Hallnor
 *          Steve Reinhardt
 */

/* @file
 * Serialization Interface Declarations
 */

#ifndef __SERIALIZE_HH__
#define __SERIALIZE_HH__


#include <iostream>
#include <list>
#include <map>
#include <vector>

#include "base/bitunion.hh"
#include "base/types.hh"

class IniFile;
class Serializable;
class Checkpoint;
class SimObject;
class EventQueue;

/** The current version of the checkpoint format.
 * This should be incremented by 1 and only 1 for every new version, where a new
 * version is defined as a checkpoint created before this version won't work on
 * the current version until the checkpoint format is updated. Adding a new
 * SimObject shouldn't cause the version number to increase, only changes to
 * existing objects such as serializing/unserializing more state, changing sizes
 * of serialized arrays, etc. */
static const uint64_t gem5CheckpointVersion = 0x000000000000000d;

template <class T>
void paramOut(std::ostream &os, const std::string &name, const T &param);

template <typename DataType, typename BitUnion>
void paramOut(std::ostream &os, const std::string &name,
              const BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
{
    paramOut(os, name, p.__data);
}

template <class T>
void paramIn(Checkpoint *cp, const std::string &section,
             const std::string &name, T &param);

template <typename DataType, typename BitUnion>
void paramIn(Checkpoint *cp, const std::string &section,
             const std::string &name,
             BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
{
    paramIn(cp, section, name, p.__data);
}

template <class T>
bool optParamIn(Checkpoint *cp, const std::string &section,
             const std::string &name, T &param);

template <typename DataType, typename BitUnion>
bool optParamIn(Checkpoint *cp, const std::string &section,
                const std::string &name,
                BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
{
    return optParamIn(cp, section, name, p.__data);
}

template <class T>
void arrayParamOut(std::ostream &os, const std::string &name,
                   const T *param, unsigned size);

template <class T>
void arrayParamOut(std::ostream &os, const std::string &name,
                   const std::vector<T> &param);

template <class T>
void arrayParamOut(std::ostream &os, const std::string &name,
                   const std::list<T> &param);

template <class T>
void arrayParamIn(Checkpoint *cp, const std::string &section,
                  const std::string &name, T *param, unsigned size);

template <class T>
void arrayParamIn(Checkpoint *cp, const std::string &section,
                  const std::string &name, std::vector<T> &param);

template <class T>
void arrayParamIn(Checkpoint *cp, const std::string &section,
                  const std::string &name, std::list<T> &param);

void
objParamIn(Checkpoint *cp, const std::string &section,
           const std::string &name, SimObject * &param);

template <typename T>
void fromInt(T &t, int i)
{
    t = (T)i;
}

template <typename T>
void fromSimObject(T &t, SimObject *s)
{
    t = dynamic_cast<T>(s);
}

//
// These macros are streamlined to use in serialize/unserialize
// functions.  It's assumed that serialize() has a parameter 'os' for
// the ostream, and unserialize() has parameters 'cp' and 'section'.
#define SERIALIZE_SCALAR(scalar)        paramOut(os, #scalar, scalar)

#define UNSERIALIZE_SCALAR(scalar)      paramIn(cp, section, #scalar, scalar)
#define UNSERIALIZE_OPT_SCALAR(scalar)      optParamIn(cp, section, #scalar, scalar)

// ENUMs are like SCALARs, but we cast them to ints on the way out
#define SERIALIZE_ENUM(scalar)          paramOut(os, #scalar, (int)scalar)

#define UNSERIALIZE_ENUM(scalar)                \
 do {                                           \
    int tmp;                                    \
    paramIn(cp, section, #scalar, tmp);         \
    fromInt(scalar, tmp);                    \
  } while (0)

#define SERIALIZE_ARRAY(member, size)           \
        arrayParamOut(os, #member, member, size)

#define UNSERIALIZE_ARRAY(member, size)         \
        arrayParamIn(cp, section, #member, member, size)

#define SERIALIZE_OBJPTR(objptr)        paramOut(os, #objptr, (objptr)->name())

#define UNSERIALIZE_OBJPTR(objptr)                      \
  do {                                                  \
    SimObject *sptr;                                    \
    objParamIn(cp, section, #objptr, sptr);             \
    fromSimObject(objptr, sptr);                        \
  } while (0)

/**
 * Basic support for object serialization.
 *
 * @note Many objects that support serialization need to be put in a
 * consistent state when serialization takes place. We refer to the
 * action of forcing an object into a consistent state as
 * 'draining'. Objects that need draining inherit from Drainable. See
 * Drainable for more information.
 */
class Serializable
{
  protected:
    void nameOut(std::ostream &os);
    void nameOut(std::ostream &os, const std::string &_name);

  public:
    Serializable();
    virtual ~Serializable();

    // manditory virtual function, so objects must provide names
    virtual const std::string name() const = 0;

    virtual void serialize(std::ostream &os);
    virtual void unserialize(Checkpoint *cp, const std::string &section);

    static Serializable *create(Checkpoint *cp, const std::string &section);

    static int ckptCount;
    static int ckptMaxCount;
    static int ckptPrevCount;
    static void serializeAll(const std::string &cpt_dir);
    static void unserializeGlobals(Checkpoint *cp);
};

void debug_serialize(const std::string &cpt_dir);

//
// A SerializableBuilder serves as an evaluation context for a set of
// parameters that describe a specific instance of a Serializable.  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
// Serializable references.  SerializableBuilder is an abstract superclass;
// derived classes specialize the class for particular subclasses of
// Serializable (e.g., BaseCache).
//
// For typical usage, see the definition of
// SerializableClass::createObject().
//
class SerializableBuilder
{
  public:

    SerializableBuilder() {}

    virtual ~SerializableBuilder() {}

    // Create the actual Serializable 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 Serializable.
    virtual Serializable *create() = 0;
};

//
// An instance of SerializableClass corresponds to a class derived from
// Serializable.  The SerializableClass 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 SerializableClass
{
  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 SerializableBuilder is returned.
    typedef Serializable *(*CreateFunc)(Checkpoint *cp,
                                        const std::string &section);

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

    // Constructor.  For example:
    //
    // SerializableClass baseCacheSerializableClass("BaseCacheSerializable",
    //                         newBaseCacheSerializableBuilder);
    //
    SerializableClass(const std::string &className, CreateFunc createFunc);

    // create Serializable given name of class and pointer to
    // configuration hierarchy node
    static Serializable *createObject(Checkpoint *cp,
                                      const std::string &section);
};

//
// Macros to encapsulate the magic of declaring & defining
// SerializableBuilder and SerializableClass objects
//

#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS)                      \
SerializableClass the##OBJ_CLASS##Class(CLASS_NAME,                        \
                                         OBJ_CLASS::createForUnserialize);

// Base class to wrap object resolving functionality.  This can be
// provided to Checkpoint to allow it to map object names onto
// object C++ objects in which to unserialize
class SimObjectResolver
{
  public:
    virtual ~SimObjectResolver() { }

    // Find a SimObject given a full path name
    virtual SimObject *resolveSimObject(const std::string &name) = 0;
};

class Checkpoint
{
  private:

    IniFile *db;

    SimObjectResolver &objNameResolver;

  public:
    Checkpoint(const std::string &cpt_dir, SimObjectResolver &resolver);
    ~Checkpoint();

    const std::string cptDir;

    bool find(const std::string &section, const std::string &entry,
              std::string &value);

    bool findObj(const std::string &section, const std::string &entry,
                 SimObject *&value);

    bool sectionExists(const std::string &section);

    // The following static functions have to do with checkpoint
    // creation rather than restoration.  This class makes a handy
    // namespace for them though.  Currently no Checkpoint object is
    // created on serialization (only unserialization) so we track the
    // directory name as a global.  It would be nice to change this
    // someday

  private:
    // current directory we're serializing into.
    static std::string currentDirectory;

  public:
    // Set the current directory.  This function takes care of
    // inserting curTick() if there's a '%d' in the argument, and
    // appends a '/' if necessary.  The final name is returned.
    static std::string setDir(const std::string &base_name);

    // Export current checkpoint directory name so other objects can
    // derive filenames from it (e.g., memory).  The return value is
    // guaranteed to end in '/' so filenames can be directly appended.
    // This function is only valid while a checkpoint is being created.
    static std::string dir();

    // Filename for base checkpoint file within directory.
    static const char *baseFilename;
};

#endif // __SERIALIZE_HH__
