/*
 * Copyright (c) 2014 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) 2006-2009 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: Ali Saidi
 */

#ifndef __BASE__CP_ANNOTATE_HH__
#define __BASE__CP_ANNOTATE_HH__

#include <list>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "debug/AnnotateQ.hh"
#include "config/cp_annotate.hh"
#include "config/the_isa.hh"
#include "sim/serialize.hh"
#include "sim/system.hh"

#if CP_ANNOTATE
#include "params/CPA.hh"
#endif

class System;
class ThreadContext;


#if !CP_ANNOTATE
class CPA
{
  public:
    enum flags {
        FL_NONE     = 0x00,
        FL_HW       = 0x01,
        FL_BAD      = 0x02,
        FL_QOPP     = 0x04,
        FL_WAIT     = 0x08,
        FL_LINK     = 0x10,
        FL_RESET    = 0x20
    };

    static CPA *cpa()                                        { return NULL; }
    static bool available()                                 { return false; }
    bool enabled()                                          { return false; }
    void swSmBegin(ThreadContext *tc)                             { return; }
    void swSmEnd(ThreadContext *tc)                               { return; }
    void swExplictBegin(ThreadContext *tc)                        { return; }
    void swAutoBegin(ThreadContext *tc, Addr next_pc)             { return; }
    void swEnd(ThreadContext *tc)                                 { return; }
    void swQ(ThreadContext *tc)                                   { return; }
    void swDq(ThreadContext *tc)                                  { return; }
    void swPq(ThreadContext *tc)                                  { return; }
    void swRq(ThreadContext *tc)                                  { return; }
    void swWf(ThreadContext *tc)                                  { return; }
    void swWe(ThreadContext *tc)                                  { return; }
    void swSq(ThreadContext *tc)                                  { return; }
    void swAq(ThreadContext *tc)                                  { return; }
    void swLink(ThreadContext *tc)                                { return; }
    void swIdentify(ThreadContext *tc)                            { return; }
    uint64_t swGetId(ThreadContext *tc)                         { return 0; }
    void swSyscallLink(ThreadContext *tc)                         { return; }
    void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
                 std::string st)                                  { return; }
    void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
             std::string q, uint64_t qid, System *q_sys = NULL,
             int32_t count = 1)                                   { return; }
    void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
              std::string q, uint64_t qid, System *q_sys = NULL,
              int32_t count = 1)                                  { return; }
    void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
              std::string q, uint64_t qid, System *q_sys = NULL,
              int32_t count = 1)                                  { return; }
    void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
              std::string q, uint64_t qid, System *q_sys = NULL,
              int32_t count = 1)                                  { return; }
    void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
              std::string q, uint64_t qid, System *q_sys = NULL,
              int32_t count = 1)                                  { return; }
    void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
              std::string q, uint64_t qid, System *q_sys = NULL,
              int32_t count = 1)                                  { return; }
};
#else

/**
 * Provide a hash function for the CPI Id type
 */
namespace std {
template <>
struct hash<std::pair<std::string, uint64_t> >
{

    size_t
    operator()(const std::pair<std::string, uint64_t>& x) const
    {
        return hash<std::string>()(x.first);
    }

};
}

class CPA : SimObject
{
  public:
    typedef CPAParams Params;

    /** The known operations that are written to the annotation output file. */
    enum ops {
        OP_BEGIN           = 0x01,
        OP_WAIT_EMPTY      = 0x02,
        OP_WAIT_FULL       = 0x03,
        OP_QUEUE           = 0x04,
        OP_DEQUEUE         = 0x05,
        OP_SIZE_QUEUE      = 0x08,
        OP_PEEK            = 0x09,
        OP_LINK            = 0x0A,
        OP_IDENT           = 0x0B,
        OP_RESERVE         = 0x0C
    };

    /** Flags for the various options.*/
    enum flags {
        /* no flags */
        FL_NONE     = 0x00,
        /* operation was done on hardware */
        FL_HW       = 0x01,
        /* operation should cause a warning when encountered */
        FL_BAD      = 0x02,
        /* Queue like a stack, not a queue */
        FL_QOPP     = 0x04,
        /* Mark HW state as waiting for some non-resource constraint
         * (e.g. wait because SM only starts after 10 items are queued) */
        FL_WAIT     = 0x08,
        /* operation is linking to another state machine */
        FL_LINK     = 0x10,
        /* queue should be completely cleared/reset before executing this
         * operation */
        FL_RESET    = 0x20
    };



  protected:
    const Params *
        params() const
        {
            return dynamic_cast<const Params *>(_params);
        }

    /* struct that is written to the annotation output file */
    struct AnnotateData : public Serializable {

        Tick time;
        uint32_t data;
        uint32_t orig_data;
        uint16_t sm;
        uint16_t stq;
        uint8_t  op;
        uint8_t  flag;
        uint8_t  cpu;
        bool dump;

        void serialize(CheckpointOut &cp) const override;
        void unserialize(CheckpointIn &cp) override;
    };

    typedef std::shared_ptr<AnnotateData> AnnDataPtr;

    /* header for the annotation file */
    struct AnnotateHeader {
        uint64_t version;
        uint64_t num_recs;
        uint64_t key_off;
        uint64_t idx_off;
        uint32_t key_len;
        uint32_t idx_len;
    };

    AnnotateHeader ah;

    std::vector<uint64_t> annotateIdx;

    // number of state machines encountered in the simulation
    int numSm;
    // number of states encountered in the simulation
    int numSmt;
    // number of states/queues for a given state machine/system respectively
    std::vector<int> numSt, numQ;
    // number of systems in the simulation
    int numSys;
    // number of queues in the state machine
    int numQs;
    // maximum connection id assigned so far
    uint64_t conId;

    // Convert state strings into state ids
    typedef std::unordered_map<std::string, int> SCache;
    typedef std::vector<SCache> StCache;

    // Convert sm and queue name,id into queue id
    typedef std::pair<std::string, uint64_t> Id;
    typedef std::unordered_map<Id, int> IdHCache;
    typedef std::vector<IdHCache> IdCache;

    // Hold mapping of sm and queues to output python
    typedef std::vector<std::pair<int, Id> > IdMap;

    // System pointer to name,id
    typedef std::map<System*, std::pair<std::string, int> > NameCache;

    // array of systems each of which is a stack of running sm
    typedef std::pair<int, uint64_t> StackId;
    typedef std::map<StackId, std::vector<int> > SmStack;

    // map of each context and if it's currently in explict state mode
    // states are not automatically updated until it leaves
    typedef std::map<StackId, bool> SwExpl;

    typedef std::map<int,int> IMap;
    // List of annotate records have not been written/completed yet
    typedef std::list<AnnDataPtr> AnnotateList;

    // Maintain link state information
    typedef std::map<int, int> LinkMap;

    // SC Links
    typedef std::unordered_map<Id, AnnDataPtr> ScHCache;
    typedef std::vector<ScHCache> ScCache;


    AnnotateList data;

    // vector indexed by queueid to find current number of elements and bytes
    std::vector<int> qSize;
    std::vector<int32_t> qBytes;


    // Turn state machine string into state machine id (small int)
    // Used for outputting key to convert id back into string
    SCache smtCache;
    // Turn state machine id, state name into state id (small int)
    StCache stCache;
    // turn system, queue, and queue identify into qid (small int)
    // turn system, state, and context into state machine id (small int)
    IdCache qCache, smCache;
    //Link state machines accross system calls
    ScCache scLinks;
    // System pointer to name,id
    NameCache nameCache;
    // Stack of state machines currently nested (should unwind correctly)
    SmStack smStack;
    // Map of currently outstanding links
    LinkMap lnMap;
    // If the state machine is currently exculding automatic changes
    SwExpl swExpl;
    // Last state that a given state machine was in
    IMap lastState;
    // Hold mapping of sm and queues to output python
    IdMap smMap, qMap;
    // Items still in queue, used for sanity checking
    std::vector<AnnotateList> qData;

    void doDq(System *sys, int flags, int cpu, int sm, std::string q, int qi,
            int count);
    void doQ(System *sys, int flags, int cpu, int sm, std::string q, int qi,
            int count);

    void doSwSmEnd(System *sys, int cpuid, std::string sm, uint64_t frame);

    // Turn a system id, state machine string, state machine id into a small int
    // for annotation output
    int
    getSm(int sysi, std::string si, uint64_t id)
    {
        int smi;
        Id smid = Id(si, id);

        smi = smCache[sysi-1][smid];
        if (smi == 0) {
            smCache[sysi-1][smid] = smi = ++numSm;
            assert(smi < 65535);
            smMap.push_back(std::make_pair(sysi, smid));
        }
        return smi;
    }

    // Turn a state machine string, state string into a small int
    // for annotation output
    int
    getSt(std::string sm, std::string s)
    {
        int sti, smi;

        smi = smtCache[sm];
        if (smi == 0)
           smi = smtCache[sm] = ++numSmt;

        while (stCache.size() < smi) {
            //stCache.resize(sm);
            stCache.push_back(SCache());
            numSt.push_back(0);
        }
        //assert(stCache.size() == sm);
        //assert(numSt.size() == sm);
        sti = stCache[smi-1][s];
        if (sti == 0)
            stCache[smi-1][s] = sti = ++numSt[smi-1];
        return sti;
    }

    // Turn state machine pointer into a smal int for annotation output
    int
    getSys(System *s)
    {
        NameCache::iterator i = nameCache.find(s);
        if (i == nameCache.end()) {
            nameCache[s] = std::make_pair(s->name(), ++numSys);
            i = nameCache.find(s);
            // might need to put smstackid into map here, but perhaps not
            //smStack.push_back(std::vector<int>());
            //swExpl.push_back(false);
            numQ.push_back(0);
            qCache.push_back(IdHCache());
            smCache.push_back(IdHCache());
            scLinks.push_back(ScHCache());
        }
        return i->second.second;
    }

    // Turn queue name, and queue context into small int for
    // annotation output
    int
    getQ(int sys, std::string q, uint64_t id)
    {
        int qi;
        Id qid = Id(q, id);

        qi = qCache[sys-1][qid];
        if (qi == 0) {
            qi = qCache[sys-1][qid] = ++numQs;
            assert(qi < 65535);
            qSize.push_back(0);
            qBytes.push_back(0);
            qData.push_back(AnnotateList());
            numQ[sys-1]++;
            qMap.push_back(std::make_pair(sys, qid));
        }
        return qi;
    }

    void swBegin(System *sys, int cpuid, std::string st, uint64_t frame,
            bool expl = false, int flags = FL_NONE);

    AnnDataPtr add(int t, int f, int c, int sm, int stq, int32_t data=0);

    std::ostream *osbin;

    bool _enabled;

    /** Only allow one CPA object in a system. It doesn't make sense to have
     * more that one per simulation because if a part of the system was
     * important it would have annotations and queues, and with more than one
     * object none of the sanity checking for queues will work. */
    static bool exists;
    static CPA *_cpa;


    std::map<std::string, SymbolTable*> userApp;

  public:
    static CPA *cpa() { return _cpa; }
    void swSmBegin(ThreadContext *tc);
    void swSmEnd(ThreadContext *tc);
    void swExplictBegin(ThreadContext *tc);
    void swAutoBegin(ThreadContext *tc, Addr next_pc);
    void swEnd(ThreadContext *tc);
    void swQ(ThreadContext *tc);
    void swDq(ThreadContext *tc);
    void swPq(ThreadContext *tc);
    void swRq(ThreadContext *tc);
    void swWf(ThreadContext *tc);
    void swWe(ThreadContext *tc);
    void swSq(ThreadContext *tc);
    void swAq(ThreadContext *tc);
    void swLink(ThreadContext *tc);
    void swIdentify(ThreadContext *tc);
    uint64_t swGetId(ThreadContext *tc);
    void swSyscallLink(ThreadContext *tc);

    inline void hwBegin(flags f, System *sys, uint64_t frame, std::string sm,
            std::string st)
    {
        if (!enabled())
            return;

        int sysi = getSys(sys);
        int smi = getSm(sysi, sm, frame);
        add(OP_BEGIN, FL_HW | f, 0, smi, getSt(sm, st));
        if (f & FL_BAD)
            warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
    }

    inline void hwQ(flags f, System *sys, uint64_t frame, std::string sm,
            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
    {
        if (!enabled())
            return;

        int sysi = getSys(sys);
        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
        DPRINTFS(AnnotateQ, sys,
                "hwQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
        doQ(sys, FL_HW | f, 0, getSm(sysi, sm, frame), q, qi, count);

    }

    inline void hwDq(flags f, System *sys, uint64_t frame, std::string sm,
            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
    {
        if (!enabled())
            return;

        int sysi = getSys(sys);
        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
        DPRINTFS(AnnotateQ, sys,
                "hwDQ: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
        doDq(sys, FL_HW | f, 0, getSm(sysi,sm, frame), q, qi, count);
    }

    inline void hwPq(flags f, System *sys, uint64_t frame, std::string sm,
            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
    {
        if (!enabled())
            return;

        int sysi = getSys(sys);
        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
        DPRINTFS(AnnotateQ, sys,
                "hwPQ: %s[%#x] cur size %d %d bytes: %d peeking: %d\n",
                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
        add(OP_PEEK, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
    }

    inline void hwRq(flags f, System *sys, uint64_t frame, std::string sm,
            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
    {
        if (!enabled())
            return;

        int sysi = getSys(sys);
        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
        DPRINTFS(AnnotateQ, sys,
                "hwRQ: %s[%#x] cur size %d %d bytes: %d reserving: %d\n",
                q, qid, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
        add(OP_RESERVE, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
    }

    inline void hwWf(flags f, System *sys, uint64_t frame, std::string sm,
            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
    {
        if (!enabled())
            return;

        int sysi = getSys(sys);
        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
        add(OP_WAIT_FULL, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
    }

    inline void hwWe(flags f, System *sys, uint64_t frame, std::string sm,
            std::string q, uint64_t qid, System *q_sys = NULL, int32_t count = 1)
    {
        if (!enabled())
            return;

        int sysi = getSys(sys);
        int qi = getQ(q_sys ?  getSys(q_sys) : sysi, q, qid);
        add(OP_WAIT_EMPTY, FL_HW | f, 0, getSm(sysi, sm, frame), qi, count);
    }

  public:
    CPA(Params *p);
    void startup();

    uint64_t getFrame(ThreadContext *tc);

    static bool available()  { return true; }

    bool
    enabled()
    {
        if (!this)
            return false;
        return _enabled;
    }

    void dump(bool all);
    void dumpKey();

    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;
};
#endif // !CP_ANNOTATE

#endif //__BASE__CP_ANNOTATE_HH__

