/*
 * Copyright (c) 2012-2014, TU Delft
 * Copyright (c) 2012-2014, TU Eindhoven
 * Copyright (c) 2012-2014, TU Kaiserslautern
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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
 * HOLDER 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: Karthik Chandrasekar
 *
 */

#ifndef MEMCOMMAND_H
#define MEMCOMMAND_H

#include <stdint.h>
#include <cassert>
#include <string>

#include "MemorySpecification.h"

namespace Data {
class MemCommand {
 public:
  /*
   * 1. ACT - Activate
   * 2. RD - Read
   * 3. WR - Write
   * 4. PRE - Explicit Precharge per bank
   * 5. REF - Refresh all banks
   * 6  REFB- Refresh a particular bank
   * 7. END - To indicate end of trace
   * 8. RDA - Read with auto-precharge
   * 9. WRA - Write with auto-precharge
   * 10. PREA - Precharge all banks
   * 11. PDN_F_PRE - Precharge Power-down Entry command (Fast-Exit)
   * 12. PDN_S_PRE - Precharge Power-down Entry command (Slow-Exit)
   * 13. PDN_F_ACT - Active Power-down Entry command (Fast-Exit)
   * 14. PDN_S_ACT - Active Power-down Entry command (Slow-Exit)
   * 15. PUP_PRE - Precharge Power-down Exit
   * 16. PUP_ACT - Active Power-down Exit
   * 17. SREN - Self-Refresh Entry command
   * 18. SREX - Self-refresh Exit
   * 19. NOP - To indicate end of trace
   */

  enum cmds {
    ACT       = 0,
    RD        = 1,
    WR        = 2,
    PRE       = 3,
    REF       = 4,
    REFB      = 5,
    END       = 6,
    RDA       = 7,
    WRA       = 8,
    PREA      = 9,
    PDN_F_PRE = 10,
    PDN_S_PRE = 11,
    PDN_F_ACT = 12,
    PDN_S_ACT = 13,
    PUP_PRE   = 14,
    PUP_ACT   = 15,
    SREN      = 16,
    SREX      = 17,
    NOP       = 18,
    UNINITIALIZED = 19
  };

//  MemCommand();
  MemCommand(
    // Command Type
    MemCommand::cmds type = UNINITIALIZED,
    // Target Bank
    unsigned         bank = 0,
    // Command Issue Timestamp (in cc)
    int64_t          timestamp = 0L);

  // Get command type
  cmds getType() const;

  // Set command type
  void setType(MemCommand::cmds type);

  // Set target Bank
  void setBank(unsigned bank);

  // Get target Bank
  unsigned getBank() const;

  // Set timestamp
  void setTime(int64_t _timestamp);

  // Get timestamp
  int64_t getTimeInt64() const;

  cmds typeWithoutAutoPrechargeFlag() const;

  // To calculate precharge offset after read or write with auto-precharge
  int64_t getPrechargeOffset(const MemorySpecification& memSpec,
                         MemCommand::cmds           type) const;

  // To check for equivalence

  bool operator==(const MemCommand& other) const
  {
    if ((getType() == other.getType()) &&
        (getBank() == other.getBank())
        ) {
      return true;
    } else {
      return false;
    }
  }

  static const unsigned int nCommands = 20;

  static std::string* getCommandTypeStrings()
  {
    static std::string type_map[nCommands] = { "ACT",
                                               "RD",
                                               "WR",
                                               "PRE",
                                               "REF",
                                               "REFB",
                                               "END",
                                               "RDA",
                                               "WRA",
                                               "PREA",
                                               "PDN_F_PRE",
                                               "PDN_S_PRE",
                                               "PDN_F_ACT",
                                               "PDN_S_ACT",
                                               "PUP_PRE",
                                               "PUP_ACT",
                                               "SREN",
                                               "SREX",
                                               "NOP",
                                               "UNINITIALIZED" };

    return type_map;
  }

  // To identify command type from name
  static cmds getTypeFromName(const std::string& name)
  {
    std::string* typeStrings = getCommandTypeStrings();

    for (size_t typeId = 0; typeId < nCommands; typeId++) {
      if (typeStrings[typeId] == name) {
        cmds commandType = static_cast<cmds>(typeId);
        return commandType;
      }
    }
    assert(false); // Unknown name.
    return NOP;  // For clang compilation
  }

 private:
  MemCommand::cmds type;
  unsigned bank;
  int64_t timestamp;
};
}
#endif // ifndef MEMCOMMAND_H
