/*
 * 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 __BASE_STATS_INFO_HH__
#define __BASE_STATS_INFO_HH__

#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/compiler.hh"
#include "base/flags.hh"
#include "base/stats/types.hh"
#include "base/stats/units.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Stats, statistics);
namespace statistics
{

typedef uint16_t FlagsType;
typedef gem5::Flags<FlagsType> Flags;

/** Nothing extra to print. */
const FlagsType none =          0x0000;
/** This Stat is Initialized */
const FlagsType init =          0x0001;
/** Print this stat. */
const FlagsType display =       0x0002;
/** Print the total. */
const FlagsType total =         0x0010;
/** Print the percent of the total that this entry represents. */
const FlagsType pdf =           0x0020;
/** Print the cumulative percentage of total upto this entry. */
const FlagsType cdf =           0x0040;
/** Print the distribution. */
const FlagsType dist =          0x0080;
/** Don't print if this is zero. */
const FlagsType nozero =        0x0100;
/** Don't print if this is NAN */
const FlagsType nonan =         0x0200;
/** Print all values on a single line. Useful only for histograms. */
const FlagsType oneline =       0x0400;

/** Mask of flags that can't be set directly */
const FlagsType __reserved =    init | display;

struct StorageParams;
struct Output;

class Info
{
  public:
    /** The name of the stat. */
    std::string name;
    /** The separator string used for vectors, dist, etc. */
    static std::string separatorString;
    /** The unit of the stat. */
    const units::Base* unit = units::Unspecified::get();
    /** The description of the stat. */
    std::string desc;
    /** The formatting flags. */
    Flags flags;
    /** The display precision. */
    int precision;
    /** A pointer to a prerequisite Stat. */
    const Info *prereq;
    /**
     * A unique stat ID for each stat in the simulator.
     * Can be used externally for lookups as well as for debugging.
     */
    static int id_count;
    int id;

  private:
    std::unique_ptr<const StorageParams> storageParams;

  public:
    Info();
    virtual ~Info();

    /**
     * Set the name of this statistic. Special handling must be done when
     * creating an old-style statistic (i.e., stats without a parent group).
     *
     * @param name The new name.
     * @param old_style Whether we are using the old style.
     */
    void setName(const std::string &name, bool old_style=true);

    void setSeparator(std::string _sep) { separatorString = _sep;}

    /**
     * Getter for the storage params. These parameters should only be modified
     * using the respective setter.
     * @sa setStorageParams
     */
    StorageParams const* getStorageParams() const;
    /** Setter for the storage params. */
    void setStorageParams(const StorageParams *const params);

    /**
     * Check that this stat has been set up properly and is ready for
     * use
     * @return true for success
     */
    virtual bool check() const = 0;
    bool baseCheck() const;

    /**
     * Enable the stat for use
     */
    virtual void enable();

    /**
     * Prepare the stat for dumping.
     */
    virtual void prepare() = 0;

    /**
     * Reset the stat to the default state.
     */
    virtual void reset() = 0;

    /**
     * @return true if this stat has a value and satisfies its
     * requirement as a prereq
     */
    virtual bool zero() const = 0;

    /**
     * Visitor entry for outputing statistics data
     */
    virtual void visit(Output &visitor) = 0;

    /**
     * Checks if the first stat's name is alphabetically less than the second.
     * This function breaks names up at periods and considers each subname
     * separately.
     * @param stat1 The first stat.
     * @param stat2 The second stat.
     * @return stat1's name is alphabetically before stat2's
     */
    static bool less(Info *stat1, Info *stat2);
};

class ScalarInfo : public Info
{
  public:
    virtual Counter value() const = 0;
    virtual Result result() const = 0;
    virtual Result total() const = 0;
};

class VectorInfo : public Info
{
  public:
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;

  public:
    void enable();

  public:
    virtual size_type size() const = 0;
    virtual const VCounter &value() const = 0;
    virtual const VResult &result() const = 0;
    virtual Result total() const = 0;
};

class DistInfo : public Info
{
  public:
    /** Local storage for the entry values, used for printing. */
    DistData data;
};

class VectorDistInfo : public Info
{
  public:
    std::vector<DistData> data;

    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    void enable();

  protected:
    /** Local storage for the entry values, used for printing. */
    mutable VResult rvec;

  public:
    virtual size_type size() const = 0;
};

class Vector2dInfo : public Info
{
  public:
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    std::vector<std::string> y_subnames;

    size_type x;
    size_type y;

    /** Local storage for the entry values, used for printing. */
    mutable VCounter cvec;

    void enable();

    virtual Result total() const = 0;
};

class FormulaInfo : public VectorInfo
{
  public:
    virtual std::string str() const = 0;
};

class SparseHistInfo : public Info
{
  public:
    /** Local storage for the entry values, used for printing. */
    SparseHistData data;
};

typedef std::map<std::string, Info *> NameMapType;
NameMapType &nameMap();

} // namespace statistics
} // namespace gem5

#endif // __BASE_STATS_INFO_HH__
