/*
 * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
 * 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.
 */

/*
 * Contains all of the various parts of the system we are simulating.
 * Performs allocation, deallocation, and setup of all the major
 * components of the system
 */

#ifndef __MEM_RUBY_SYSTEM_RUBYSYSTEM_HH__
#define __MEM_RUBY_SYSTEM_RUBYSYSTEM_HH__

#include <unordered_map>

#include "base/callback.hh"
#include "base/output.hh"
#include "mem/packet.hh"
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/system/CacheRecorder.hh"
#include "params/RubySystem.hh"
#include "sim/clocked_object.hh"

class Network;
class AbstractController;

class RubySystem : public ClockedObject
{
  public:
    typedef RubySystemParams Params;
    RubySystem(const Params *p);
    ~RubySystem();
    const Params *params() const { return (const Params *)_params; }

    // config accessors
    static int getRandomization() { return m_randomization; }
    static uint32_t getBlockSizeBytes() { return m_block_size_bytes; }
    static uint32_t getBlockSizeBits() { return m_block_size_bits; }
    static uint32_t getMemorySizeBits() { return m_memory_size_bits; }
    static bool getWarmupEnabled() { return m_warmup_enabled; }
    static bool getCooldownEnabled() { return m_cooldown_enabled; }

    SimpleMemory *getPhysMem() { return m_phys_mem; }
    Cycles getStartCycle() { return m_start_cycle; }
    bool getAccessBackingStore() { return m_access_backing_store; }

    // Public Methods
    Profiler*
    getProfiler()
    {
        assert(m_profiler != NULL);
        return m_profiler;
    }

    void regStats() override {
        ClockedObject::regStats();
        m_profiler->regStats(name());
    }
    void collateStats() { m_profiler->collateStats(); }
    void resetStats() override;

    void memWriteback() override;
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;
    void drainResume() override;
    void process();
    void init() override;
    void startup() override;
    bool functionalRead(Packet *ptr);
    bool functionalWrite(Packet *ptr);

    void registerNetwork(Network*);
    void registerAbstractController(AbstractController*);
    void registerMachineID(const MachineID& mach_id, Network* network);
    void registerRequestorIDs();

    bool eventQueueEmpty() { return eventq->empty(); }
    void enqueueRubyEvent(Tick tick)
    {
        auto e = new EventFunctionWrapper(
            [this]{ processRubyEvent(); }, "RubyEvent");
        schedule(e, tick);
    }

  private:
    // Private copy constructor and assignment operator
    RubySystem(const RubySystem& obj);
    RubySystem& operator=(const RubySystem& obj);

    void makeCacheRecorder(uint8_t *uncompressed_trace,
                           uint64_t cache_trace_size,
                           uint64_t block_size_bytes);

    static void readCompressedTrace(std::string filename,
                                    uint8_t *&raw_data,
                                    uint64_t &uncompressed_trace_size);
    static void writeCompressedTrace(uint8_t *raw_data, std::string file,
                                     uint64_t uncompressed_trace_size);

    void processRubyEvent();
  private:
    // configuration parameters
    static bool m_randomization;
    static uint32_t m_block_size_bytes;
    static uint32_t m_block_size_bits;
    static uint32_t m_memory_size_bits;

    static bool m_warmup_enabled;
    static unsigned m_systems_to_warmup;
    static bool m_cooldown_enabled;
    SimpleMemory *m_phys_mem;
    const bool m_access_backing_store;

    //std::vector<Network *> m_networks;
    std::vector<std::unique_ptr<Network>> m_networks;
    std::vector<AbstractController *> m_abs_cntrl_vec;
    Cycles m_start_cycle;

    std::unordered_map<MachineID, unsigned> machineToNetwork;
    std::unordered_map<RequestorID, unsigned> requestorToNetwork;
    std::unordered_map<unsigned, std::vector<AbstractController*>> netCntrls;

  public:
    Profiler* m_profiler;
    CacheRecorder* m_cache_recorder;
    std::vector<std::map<uint32_t, AbstractController *> > m_abstract_controls;
};

#endif //__MEM_RUBY_SYSTEM_RUBYSYSTEM_HH__
