/*
 * Copyright (c) 2015, 2018, 2020 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.
 *
 * 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.
 */

/* @file
 * Serialization Interface Declarations
 */

#ifndef __SERIALIZE_HH__
#define __SERIALIZE_HH__


#include <algorithm>
#include <iostream>
#include <iterator>
#include <stack>
#include <set>
#include <type_traits>
#include <unordered_map>
#include <vector>

#include "base/inifile.hh"
#include "base/logging.hh"
#include "sim/serialize_handlers.hh"

class IniFile;
class SimObject;
class SimObjectResolver;

typedef std::ostream CheckpointOut;

class CheckpointIn
{
  private:

    IniFile *db;

    SimObjectResolver &objNameResolver;

    const std::string _cptDir;

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

    /**
     * @return Returns the current directory being used for creating
     * checkpoints or restoring checkpoints.
     * @ingroup api_serialize
     * @{
     */
    const std::string getCptDir() { return _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 entryExists(const std::string &section, const std::string &entry);
    bool sectionExists(const std::string &section);
    void visitSection(const std::string &section,
        IniFile::VisitSectionCallback cb);
    /** @}*/ //end of api_checkout group

    // 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.
     *
     * @ingroup api_serialize
     */
    static std::string setDir(const std::string &base_name);

    /**
     * Get the current checkout directory name
     *
     * This function exports the current checkout point 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.
     *
     * @ingroup api_serialize
     */
    static std::string dir();

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

/**
 * Basic support for object serialization.
 *
 * The Serailizable interface is used to create checkpoints. Any
 * object that implements this interface can be included in
 * gem5's checkpointing system.
 *
 * Objects that support serialization should derive from this
 * class. Such objects can largely be divided into two categories: 1)
 * True SimObjects (deriving from SimObject), and 2) child objects
 * (non-SimObjects).
 *
 * SimObjects are serialized automatically into their own sections
 * automatically by the SimObject base class (see
 * SimObject::serializeAll().
 *
 * SimObjects can contain other serializable objects that are not
 * SimObjects. Much like normal serialized members are not serialized
 * automatically, these objects will not be serialized automatically
 * and it is expected that the objects owning such serializable
 * objects call the required serialization/unserialization methods on
 * child objects. The preferred method to serialize a child object is
 * to call serializeSection() on the child, which serializes the
 * object into a new subsection in the current section. Another option
 * is to call serialize() directly, which serializes the object into
 * the current section. The latter is not recommended as it can lead
 * to naming clashes between objects.
 *
 * @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
{
  public:
    class ScopedCheckpointSection {
      public:
        /**
         * This is the constructor for Scoped checkpoint section helper
         * class.
         *
         * Scoped checkpoint helper class creates a section within a
         * checkpoint without the need for a separate serializeable
         * object. It is mainly used within the Serializable class
         * when serializing or unserializing section (see
         * serializeSection() and unserializeSection()). It
         * can also be used to maintain backwards compatibility in
         * existing code that serializes structs that are not inheriting
         * from Serializable into subsections.
         *
         * When the class is instantiated, it appends a name to the active
         * path in a checkpoint. The old path is later restored when the
         * instance is destroyed. For example, serializeSection() could be
         * implemented by instantiating a ScopedCheckpointSection and then
         * calling serialize() on an object.
         *
         * @ingroup api_serialize
         * @{
         */
        template<class CP>
        ScopedCheckpointSection(CP &cp, const char *name) {
            pushName(name);
            nameOut(cp);
        }

        template<class CP>
        ScopedCheckpointSection(CP &cp, const std::string &name) {
            pushName(name.c_str());
            nameOut(cp);
        }
        /** @}*/ //end of api_serialize group

        ~ScopedCheckpointSection();

        ScopedCheckpointSection() = delete;
        ScopedCheckpointSection(const ScopedCheckpointSection &) = delete;
        ScopedCheckpointSection &operator=(
            const ScopedCheckpointSection &) = delete;
        ScopedCheckpointSection &operator=(
            ScopedCheckpointSection &&) = delete;

      private:
        void pushName(const char *name);
        void nameOut(CheckpointOut &cp);
        void nameOut(CheckpointIn &cp) {};
    };

    /**
     * @ingroup api_serialize
     */
    Serializable();
    virtual ~Serializable();

    /**
     * Serialize an object
     *
     * Output an object's state into the current checkpoint section.
     *
     * @param cp Checkpoint state
     *
     * @ingroup api_serialize
     */
    virtual void serialize(CheckpointOut &cp) const = 0;

    /**
     * Unserialize an object
     *
     * Read an object's state from the current checkpoint section.
     *
     * @param cp Checkpoint state
     *
     * @ingroup api_serialize
     */
    virtual void unserialize(CheckpointIn &cp) = 0;

    /**
     * Serialize an object into a new section
     *
     * This method creates a new section in a checkpoint and calls
     * serialize() to serialize the current object into that
     * section. The name of the section is appended to the current
     * checkpoint path.
     *
     * @param cp Checkpoint state
     * @param name Name to append to the active path
     *
     * @ingroup api_serialize
     */
    void serializeSection(CheckpointOut &cp, const char *name) const;

    /**
     * @ingroup api_serialize
     */
    void serializeSection(CheckpointOut &cp, const std::string &name) const {
        serializeSection(cp, name.c_str());
    }

    /**
     * Unserialize an a child object
     *
     * This method loads a child object from a checkpoint. The object
     * name is appended to the active path to form a fully qualified
     * section name and unserialize() is called.
     *
     * @param cp Checkpoint state
     * @param name Name to append to the active path
     *
     * @ingroup api_serialize
     */
    void unserializeSection(CheckpointIn &cp, const char *name);

    /**
     * @ingroup api_serialize
     */
    void unserializeSection(CheckpointIn &cp, const std::string &name) {
        unserializeSection(cp, name.c_str());
    }

    /**
     * Gets the fully-qualified name of the active section
     *
     * @ingroup api_serialize
     */
    static const std::string &currentSection();

    /**
     * Serializes all the SimObjects.
     *
     * @ingroup api_serialize
     */
    static void serializeAll(const std::string &cpt_dir);

    /**
     * @ingroup api_serialize
     */
    static void unserializeGlobals(CheckpointIn &cp);

  private:
    static std::stack<std::string> path;
};

/**
 * This function is used for writing parameters to a checkpoint.
 * @param os The checkpoint to be written to.
 * @param name Name of the parameter to be set.
 * @param param Value of the parameter to be written.
 * @ingroup api_serialize
 */
template <class T>
void
paramOut(CheckpointOut &os, const std::string &name, const T &param)
{
    os << name << "=";
    ShowParam<T>::show(os, param);
    os << "\n";
}

template <class T>
bool
paramInImpl(CheckpointIn &cp, const std::string &name, T &param)
{
    const std::string &section(Serializable::currentSection());
    std::string str;
    return cp.find(section, name, str) && ParseParam<T>::parse(str, param);
}

/**
 * This function is used for restoring optional parameters from the
 * checkpoint.
 * @param cp The checkpoint to be read from.
 * @param name Name of the parameter to be read.
 * @param param Value of the parameter to be read.
 * @param do_warn If the warn is set to true then the function prints the
 * warning message.
 * @return Returns if the parameter existed in the checkpoint.
 *
 * @ingroup api_serialize
 */
template <class T>
bool
optParamIn(CheckpointIn &cp, const std::string &name, T &param,
           bool do_warn=true)
{
    if (paramInImpl(cp, name, param))
        return true;

    warn_if(do_warn, "optional parameter %s:%s not present",
            Serializable::currentSection(), name);
    return false;
}

/**
 * This function is used for restoring parameters from a checkpoint.
 * @param os The checkpoint to be restored from.
 * @param name Name of the parameter to be set.
 * @param param Value of the parameter to be restored.
 * @ingroup api_serialize
 */
template <class T>
void
paramIn(CheckpointIn &cp, const std::string &name, T &param)
{
    fatal_if(!paramInImpl(cp, name, param),
        "Can't unserialize '%s:%s'", Serializable::currentSection(), name);
}

/**
 * @ingroup api_serialize
 */
template <class InputIterator>
void
arrayParamOut(CheckpointOut &os, const std::string &name,
              InputIterator start, InputIterator end)
{
    os << name << "=";
    auto it = start;
    using Elem = std::remove_cv_t<std::remove_reference_t<decltype(*it)>>;
    if (it != end)
        ShowParam<Elem>::show(os, *it++);
    while (it != end) {
        os << " ";
        ShowParam<Elem>::show(os, *it++);
    }
    os << "\n";
}

/**
 * @ingroup api_serialize
 */
template <class T>
decltype(std::begin(std::declval<const T&>()),
         std::end(std::declval<const T&>()), void())
arrayParamOut(CheckpointOut &os, const std::string &name,
              const T &param)
{
    arrayParamOut(os, name, std::begin(param), std::end(param));
}


/**
 * @ingroup api_serialize
 */
template <class T>
void
arrayParamOut(CheckpointOut &os, const std::string &name,
              const T *param, unsigned size)
{
    arrayParamOut(os, name, param, param + size);
}

/**
 * Extract values stored in the checkpoint, and assign them to the provided
 * array container.
 *
 * @param cp The checkpoint to be parsed.
 * @param name Name of the container.
 * @param param The array container.
 * @param size The expected number of entries to be extracted.
 *
 * @ingroup api_serialize
 */

template <class T, class InsertIterator>
void
arrayParamIn(CheckpointIn &cp, const std::string &name,
             InsertIterator inserter, ssize_t fixed_size=-1)
{
    const std::string &section = Serializable::currentSection();
    std::string str;
    fatal_if(!cp.find(section, name, str),
        "Can't unserialize '%s:%s'.", section, name);

    std::vector<std::string> tokens;
    tokenize(tokens, str, ' ');

    fatal_if(fixed_size >= 0 && tokens.size() != fixed_size,
             "Array size mismatch on %s:%s (Got %u, expected %u)'\n",
             section, name, tokens.size(), fixed_size);

    for (const auto &token: tokens) {
        T value;
        fatal_if(!ParseParam<T>::parse(token, value),
                 "Could not parse \"%s\".", str);
        *inserter = value;
    }
}

/**
 * @ingroup api_serialize
 */
template <class T>
decltype(std::declval<T>().insert(std::declval<typename T::value_type>()),
         void())
arrayParamIn(CheckpointIn &cp, const std::string &name, T &param)
{
    param.clear();
    arrayParamIn<typename T::value_type>(
            cp, name, std::inserter(param, param.begin()));
}

/**
 * @ingroup api_serialize
 */
template <class T>
decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()),
         void())
arrayParamIn(CheckpointIn &cp, const std::string &name, T &param)
{
    param.clear();
    arrayParamIn<typename T::value_type>(cp, name, std::back_inserter(param));
}

/**
 * @ingroup api_serialize
 */
template <class T>
void
arrayParamIn(CheckpointIn &cp, const std::string &name,
             T *param, unsigned size)
{
    struct ArrayInserter
    {
        T *data;
        T &operator *() { return *data++; }
    } insert_it{param};

    arrayParamIn<T>(cp, name, insert_it, size);
}

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


/**
 * @ingroup api_serialize
 */
void
objParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);

/**
 * Serialize a mapping represented as two arrays: one containing names
 * and the other containing values.
 *
 * @param names array of keys
 * @param param array of values
 * @param size size of the names and param arrays
 */
template <class T>
void
mappingParamOut(CheckpointOut &os, const char* sectionName,
    const char* const names[], const T *param, unsigned size)
{
    Serializable::ScopedCheckpointSection sec(os, sectionName);
    for (unsigned i = 0; i < size; ++i) {
        paramOut(os, names[i], param[i]);
    }
}

/**
 * Restore mappingParamOut. Keys missing from the checkpoint are ignored.
 */
template <class T>
void
mappingParamIn(CheckpointIn &cp, const char* sectionName,
    const char* const names[], T *param, unsigned size)
{
    Serializable::ScopedCheckpointSection sec(cp, sectionName);
    std::unordered_map<std::string, size_t> name_to_index;
    for (size_t i = 0; i < size; i++) {
        name_to_index[names[i]] = i;
    }
    for (size_t i = 0; i < size; i++) {
        auto& key = names[i];
        T value;
        if (optParamIn(cp, key, value)) {
            param[name_to_index[key]] = value;
        }
    }
    cp.visitSection(
        Serializable::currentSection(),
        [name_to_index](const std::string& key, const std::string& val)
        {
            if (!name_to_index.count(key)) {
                warn("unknown entry found in checkpoint: %s %s %s\n",
                    Serializable::currentSection(), key, val);
            }
        }
    );
}

//
// 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'.


/**
 * \def SERIALIZE_SCALER(scaler)
 *
 * @ingroup api_serialize
 */
#define SERIALIZE_SCALAR(scalar)        paramOut(cp, #scalar, scalar)

/**
 * \def UNSERIALIZE_SCALER(scalar)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_SCALAR(scalar)      paramIn(cp, #scalar, scalar)

/**
 * \def UNSERIALIZE_OPT_SCALAR(scalar)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_OPT_SCALAR(scalar)      optParamIn(cp, #scalar, scalar)

// ENUMs are like SCALARs, but we cast them to ints on the way out

/**
 * \def SERIALIZE_ENUM(scalar)
 *
 * @ingroup api_serialize
 */
#define SERIALIZE_ENUM(scalar)          paramOut(cp, #scalar, (int)scalar)

/**
 * \def UNSERIALIZE_ENUM(scaler)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_ENUM(scalar)                        \
    do {                                                \
        int tmp;                                        \
        paramIn(cp, #scalar, tmp);                      \
        scalar = static_cast<decltype(scalar)>(tmp);    \
    } while (0)

/**
 * \def SERIALIZE_ARRAY(member, size)
 *
 * @ingroup api_serialize
 */
#define SERIALIZE_ARRAY(member, size)           \
        arrayParamOut(cp, #member, member, size)

/**
 * \def UNSERIALIZE_ARRAY(member, size)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_ARRAY(member, size)         \
        arrayParamIn(cp, #member, member, size)

/**
 * \def SERIALIZE_CONTAINER(member)
 *
 * @ingroup api_serialize
 */
#define SERIALIZE_CONTAINER(member)             \
        arrayParamOut(cp, #member, member)

/**
 * \def UNSERIALIZE_CONTAINER(member)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_CONTAINER(member)           \
        arrayParamIn(cp, #member, member)

/**
 * \def SERIALIZE_EVENT(event)
 *
 * @ingroup api_serialize
 */
#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);

/**
 * \def UNSERIALIZE_EVENT(event)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_EVENT(event)                        \
    do {                                                \
        event.unserializeSection(cp, #event);           \
        eventQueue()->checkpointReschedule(&event);     \
    } while (0)

/**
 * \def SERIALIZE_OBJ(obj)
 *
 * @ingroup api_serialize
 */
#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj)

/**
 * \def UNSERIALIZE_OBJ(obj)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj)

/**
 * \def SERIALIZE_OBJPTR(objptr)
 *
 * @ingroup api_serialize
 */
#define SERIALIZE_OBJPTR(objptr)        paramOut(cp, #objptr, (objptr)->name())

/**
 * \def UNSERIALIZE_OBJPTR(objptr)
 *
 * @ingroup api_serialize
 */
#define UNSERIALIZE_OBJPTR(objptr)                      \
    do {                                                \
        SimObject *sptr;                                \
        objParamIn(cp, #objptr, sptr);                  \
        objptr = dynamic_cast<decltype(objptr)>(sptr);  \
    } while (0)

/**
 * \def SERIALIZE_MAPPING(member, names, size)
 */
#define SERIALIZE_MAPPING(member, names, size) \
        mappingParamOut(cp, #member, names, member, size)

/**
 * \def UNSERIALIZE_MAPPING(member, names, size)
 */
#define UNSERIALIZE_MAPPING(member, names, size) \
        mappingParamIn(cp, #member, names, member, size)

#endif // __SERIALIZE_HH__
