# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# 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.

from collections import OrderedDict

from slicc.util import PairContainer
from slicc.symbols.Symbol import Symbol
from slicc.symbols.Var import Var

class DataMember(Var):
    def __init__(self, symtab, ident, location, type, code, pairs,
                 machine, init_code):
        super(DataMember, self).__init__(symtab, ident, location, type,
                                         code, pairs, machine)
        self.init_code = init_code

class Enumeration(PairContainer):
    def __init__(self, ident, pairs):
        super(Enumeration, self).__init__(pairs)
        self.ident = ident
        self.primary = False

class Type(Symbol):
    def __init__(self, table, ident, location, pairs, machine=None):
        super(Type, self).__init__(table, ident, location, pairs)
        self.c_ident = ident
        self.abstract_ident = ""
        if machine:
            if self.isExternal or self.isPrimitive:
                if "external_name" in self:
                    self.c_ident = self["external_name"]
            else:
                # Append with machine name
                self.c_ident = "%s_%s" % (machine, ident)

        self.pairs.setdefault("desc", "No description avaliable")

        # check for interface that this Type implements
        if "interface" in self:
            interface = self["interface"]
            if interface in ("Message"):
                self["message"] = "yes"

        # FIXME - all of the following id comparisons are fragile hacks
        if self.ident in ("CacheMemory"):
            self["cache"] = "yes"

        if self.ident in ("TBETable"):
            self["tbe"] = "yes"

        if self.ident == "TimerTable":
            self["timer"] = "yes"

        if self.ident == "DirectoryMemory":
            self["dir"] = "yes"

        if self.ident == "PersistentTable":
            self["persistent"] = "yes"

        if self.ident == "Prefetcher":
            self["prefetcher"] = "yes"

        self.isMachineType = (ident == "MachineType")

        self.isStateDecl = ("state_decl" in self)
        self.statePermPairs = []

        self.data_members = OrderedDict()
        self.methods = {}
        self.enums = OrderedDict()

    @property
    def isPrimitive(self):
        return "primitive" in self

    @property
    def isMessage(self):
        return "message" in self
    @property
    def isBuffer(self):
        return "buffer" in self
    @property
    def isInPort(self):
        return "inport" in self
    @property
    def isOutPort(self):
        return "outport" in self
    @property
    def isEnumeration(self):
        return "enumeration" in self
    @property
    def isExternal(self):
        return "external" in self
    @property
    def isGlobal(self):
        return "global" in self
    @property
    def isInterface(self):
        return "interface" in self

    # Return false on error
    def addDataMember(self, ident, type, pairs, init_code):
        if ident in self.data_members:
            return False

        member = DataMember(self.symtab, ident, self.location, type,
                            "m_%s" % ident, pairs, None, init_code)

        self.data_members[ident] = member
        self.symtab.registerSym(ident, member)
        return True

    def dataMemberType(self, ident):
        return self.data_members[ident].type

    def methodId(self, name, param_type_vec):
        return '_'.join([name] + [ pt.c_ident for pt in param_type_vec ])

    def methodIdAbstract(self, name, param_type_vec):
        return '_'.join([name] + [ pt.abstract_ident for pt in param_type_vec ])

    def statePermPairAdd(self, state_name, perm_name):
        self.statePermPairs.append([state_name, perm_name])

    def addFunc(self, func):
        ident = self.methodId(func.ident, func.param_types)
        if ident in self.methods:
            return False

        self.methods[ident] = func
        return True

    def addEnum(self, ident, pairs):
        if ident in self.enums:
            return False

        self.enums[ident] = Enumeration(ident, pairs)

        # Add default
        if "default" not in self:
            self["default"] = "%s_NUM" % self.c_ident

        return True

    ## Used to check if an enum has been already used and therefore
    ## should not be used again.
    def checkEnum(self, ident):
        if ident in self.enums and not self.enums[ident].primary:
            self.enums[ident].primary = True
            return True
        return False

    def writeCodeFiles(self, path, includes):
        if self.isExternal:
            # Do nothing
            pass
        elif self.isEnumeration:
            self.printEnumHH(path)
            self.printEnumCC(path)
        else:
            # User defined structs and messages
            self.printTypeHH(path)
            self.printTypeCC(path)

    def printTypeHH(self, path):
        code = self.symtab.codeFormatter()
        code('''
/** \\file ${{self.c_ident}}.hh
 *
 *
 * Auto generated C++ code started by $__file__:$__line__
 */

#ifndef __${{self.c_ident}}_HH__
#define __${{self.c_ident}}_HH__

#include <iostream>

#include "mem/ruby/slicc_interface/RubySlicc_Util.hh"

''')

        for dm in self.data_members.values():
            if not dm.type.isPrimitive:
                code('#include "mem/ruby/protocol/$0.hh"', dm.type.c_ident)

        parent = ""
        if "interface" in self:
            code('#include "mem/ruby/protocol/$0.hh"', self["interface"])
            parent = " :  public %s" % self["interface"]

        code('''
$klass ${{self.c_ident}}$parent
{
  public:
    ${{self.c_ident}}
''', klass="class")

        if self.isMessage:
            code('(Tick curTime) : %s(curTime) {' % self["interface"])
        else:
            code('()\n\t\t{')

        code.indent()
        if not self.isGlobal:
            code.indent()
            for dm in self.data_members.values():
                ident = dm.ident
                if "default" in dm:
                    # look for default value
                    code('m_$ident = ${{dm["default"]}}; // default for this field')
                elif "default" in dm.type:
                    # Look for the type default
                    tid = dm.type.c_ident
                    code('m_$ident = ${{dm.type["default"]}}; // default value of $tid')
                else:
                    code('// m_$ident has no default')
            code.dedent()
        code('}')

        # ******** Copy constructor ********
        if not self.isGlobal:
            code('${{self.c_ident}}(const ${{self.c_ident}}&other)')

            # Call superclass constructor
            if "interface" in self:
                code('    : ${{self["interface"]}}(other)')

            code('{')
            code.indent()

            for dm in self.data_members.values():
                code('m_${{dm.ident}} = other.m_${{dm.ident}};')

            code.dedent()
            code('}')
        else:
            code('${{self.c_ident}}(const ${{self.c_ident}}&) = default;')

        # ******** Assignment operator ********

        code('${{self.c_ident}}')
        code('&operator=(const ${{self.c_ident}}&) = default;')

        # ******** Full init constructor ********
        if not self.isGlobal:
            params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
                       for dm in self.data_members.itervalues() ]
            params = ', '.join(params)

            if self.isMessage:
                params = "const Tick curTime, " + params

            code('${{self.c_ident}}($params)')

            # Call superclass constructor
            if "interface" in self:
                if self.isMessage:
                    code('    : ${{self["interface"]}}(curTime)')
                else:
                    code('    : ${{self["interface"]}}()')

            code('{')
            code.indent()
            for dm in self.data_members.values():
                code('m_${{dm.ident}} = local_${{dm.ident}};')

            code.dedent()
            code('}')

        # create a clone member
        if self.isMessage:
            code('''
MsgPtr
clone() const
{
     return std::shared_ptr<Message>(new ${{self.c_ident}}(*this));
}
''')
        else:
            code('''
${{self.c_ident}}*
clone() const
{
     return new ${{self.c_ident}}(*this);
}
''')

        if not self.isGlobal:
            # const Get methods for each field
            code('// Const accessors methods for each field')
            for dm in self.data_members.values():
                code('''
/** \\brief Const accessor method for ${{dm.ident}} field.
 *  \\return ${{dm.ident}} field
 */
const ${{dm.type.c_ident}}&
get${{dm.ident}}() const
{
    return m_${{dm.ident}};
}
''')

            # Non-const Get methods for each field
            code('// Non const Accessors methods for each field')
            for dm in self.data_members.values():
                code('''
/** \\brief Non-const accessor method for ${{dm.ident}} field.
 *  \\return ${{dm.ident}} field
 */
${{dm.type.c_ident}}&
get${{dm.ident}}()
{
    return m_${{dm.ident}};
}
''')

            #Set methods for each field
            code('// Mutator methods for each field')
            for dm in self.data_members.values():
                code('''
/** \\brief Mutator method for ${{dm.ident}} field */
void
set${{dm.ident}}(const ${{dm.type.c_ident}}& local_${{dm.ident}})
{
    m_${{dm.ident}} = local_${{dm.ident}};
}
''')

        code('void print(std::ostream& out) const;')
        code.dedent()
        code('  //private:')
        code.indent()

        # Data members for each field
        for dm in self.data_members.values():
            if "abstract" not in dm:
                const = ""
                init = ""

                # global structure
                if self.isGlobal:
                    const = "static const "

                # init value
                if dm.init_code:
                    # only global structure can have init value here
                    assert self.isGlobal
                    init = " = %s" % (dm.init_code)

                if "desc" in dm:
                    code('/** ${{dm["desc"]}} */')

                code('$const${{dm.type.c_ident}} m_${{dm.ident}}$init;')

        # Prototypes for methods defined for the Type
        for item in self.methods:
            proto = self.methods[item].prototype
            if proto:
                code('$proto')

        code.dedent()
        code('};')

        code('''
inline std::ostream&
operator<<(std::ostream& out, const ${{self.c_ident}}& obj)
{
    obj.print(out);
    out << std::flush;
    return out;
}

#endif // __${{self.c_ident}}_HH__
''')

        code.write(path, "%s.hh" % self.c_ident)

    def printTypeCC(self, path):
        code = self.symtab.codeFormatter()

        code('''
/** \\file ${{self.c_ident}}.cc
 *
 * Auto generated C++ code started by $__file__:$__line__
 */

#include <iostream>
#include <memory>

#include "mem/ruby/protocol/${{self.c_ident}}.hh"
#include "mem/ruby/system/RubySystem.hh"

using namespace std;
''')

        code('''
/** \\brief Print the state of this object */
void
${{self.c_ident}}::print(ostream& out) const
{
    out << "[${{self.c_ident}}: ";
''')

        # For each field
        code.indent()
        for dm in self.data_members.values():
            if dm.type.c_ident == "Addr":
                code('''
out << "${{dm.ident}} = " << printAddress(m_${{dm.ident}}) << " ";''')
            else:
                code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')

        code.dedent()

        # Trailer
        code('''
    out << "]";
}''')

        # print the code for the methods in the type
        for item in self.methods:
            code(self.methods[item].generateCode())

        code.write(path, "%s.cc" % self.c_ident)

    def printEnumHH(self, path):
        code = self.symtab.codeFormatter()
        code('''
/** \\file ${{self.c_ident}}.hh
 *
 * Auto generated C++ code started by $__file__:$__line__
 */

#ifndef __${{self.c_ident}}_HH__
#define __${{self.c_ident}}_HH__

#include <iostream>
#include <string>

''')
        if self.isStateDecl:
            code('#include "mem/ruby/protocol/AccessPermission.hh"')

        if self.isMachineType:
            code('#include <functional>')
            code('#include "base/logging.hh"')
            code('#include "mem/ruby/common/Address.hh"')
            code('#include "mem/ruby/common/TypeDefines.hh"')
            code('struct MachineID;')

        code('''

// Class definition
/** \\enum ${{self.c_ident}}
 *  \\brief ${{self.desc}}
 */
enum ${{self.c_ident}} {
    ${{self.c_ident}}_FIRST,
''')

        code.indent()
        # For each field
        for i,(ident,enum) in enumerate(self.enums.iteritems()):
            desc = enum.get("desc", "No description avaliable")
            if i == 0:
                init = ' = %s_FIRST' % self.c_ident
            else:
                init = ''
            code('${{self.c_ident}}_${{enum.ident}}$init, /**< $desc */')
        code.dedent()
        code('''
    ${{self.c_ident}}_NUM
};

// Code to convert from a string to the enumeration
${{self.c_ident}} string_to_${{self.c_ident}}(const std::string& str);

// Code to convert state to a string
std::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj);

// Code to increment an enumeration type
${{self.c_ident}} &operator++(${{self.c_ident}} &e);
''')

        if self.isMachineType:
            code('''

// define a hash function for the MachineType class
namespace std {
template<>
struct hash<MachineType> {
    std::size_t operator()(const MachineType &mtype) const {
        return hash<size_t>()(static_cast<size_t>(mtype));
    }
};
}

''')
        # MachineType hack used to set the base component id for each Machine
        if self.isMachineType:
            code('''
int ${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj);
MachineType ${{self.c_ident}}_from_base_level(int);
int ${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj);
int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj);
''')

            for enum in self.enums.itervalues():
                code('''

MachineID get${{enum.ident}}MachineID(NodeID RubyNode);
''')

        if self.isStateDecl:
            code('''

// Code to convert the current state to an access permission
AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj);

''')

        # Trailer
        code('''
std::ostream& operator<<(std::ostream& out, const ${{self.c_ident}}& obj);

#endif // __${{self.c_ident}}_HH__
''')

        code.write(path, "%s.hh" % self.c_ident)

    def printEnumCC(self, path):
        code = self.symtab.codeFormatter()
        code('''
/** \\file ${{self.c_ident}}.hh
 *
 * Auto generated C++ code started by $__file__:$__line__
 */

#include <cassert>
#include <iostream>
#include <string>

#include "base/logging.hh"
#include "mem/ruby/protocol/${{self.c_ident}}.hh"

using namespace std;

''')

        if self.isStateDecl:
            code('''
// Code to convert the current state to an access permission
AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj)
{
    switch(obj) {
''')
            # For each case
            code.indent()
            for statePerm in self.statePermPairs:
                code('  case ${{self.c_ident}}_${{statePerm[0]}}:')
                code('    return AccessPermission_${{statePerm[1]}};')
            code.dedent()
            code ('''
      default:
        panic("Unknown state access permission converstion for ${{self.c_ident}}");
    }
}

''')

        if self.isMachineType:
            for enum in self.enums.itervalues():
                if enum.primary:
                    code('#include "mem/ruby/protocol/${{enum.ident}}'
                            '_Controller.hh"')
            code('#include "mem/ruby/common/MachineID.hh"')

        code('''
// Code for output operator
ostream&
operator<<(ostream& out, const ${{self.c_ident}}& obj)
{
    out << ${{self.c_ident}}_to_string(obj);
    out << flush;
    return out;
}

// Code to convert state to a string
string
${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj)
{
    switch(obj) {
''')

        # For each field
        code.indent()
        for enum in self.enums.itervalues():
            code('  case ${{self.c_ident}}_${{enum.ident}}:')
            code('    return "${{enum.ident}}";')
        code.dedent()

        # Trailer
        code('''
      default:
        panic("Invalid range for type ${{self.c_ident}}");
    }
}

// Code to convert from a string to the enumeration
${{self.c_ident}}
string_to_${{self.c_ident}}(const string& str)
{
''')

        # For each field
        start = ""
        code.indent()
        for enum in self.enums.itervalues():
            code('${start}if (str == "${{enum.ident}}") {')
            code('    return ${{self.c_ident}}_${{enum.ident}};')
            start = "} else "
        code.dedent()

        code('''
    } else {
        panic("Invalid string conversion for %s, type ${{self.c_ident}}", str);
    }
}

// Code to increment an enumeration type
${{self.c_ident}}&
operator++(${{self.c_ident}}& e)
{
    assert(e < ${{self.c_ident}}_NUM);
    return e = ${{self.c_ident}}(e+1);
}
''')

        # MachineType hack used to set the base level and number of
        # components for each Machine
        if self.isMachineType:
            code('''
/** \\brief returns the base vector index for each machine type to be
  * used by NetDest
  *
  * \\return the base vector index for each machine type to be used by NetDest
  * \\see NetDest.hh
  */
int
${{self.c_ident}}_base_level(const ${{self.c_ident}}& obj)
{
    switch(obj) {
''')

            # For each field
            code.indent()
            for i,enum in enumerate(self.enums.itervalues()):
                code('  case ${{self.c_ident}}_${{enum.ident}}:')
                code('    return $i;')
            code.dedent()

            # total num
            code('''
      case ${{self.c_ident}}_NUM:
        return ${{len(self.enums)}};

      default:
        panic("Invalid range for type ${{self.c_ident}}");
    }
}

/** \\brief returns the machine type for each base vector index used by NetDest
 *
 * \\return the MachineType
 */
MachineType
${{self.c_ident}}_from_base_level(int type)
{
    switch(type) {
''')

            # For each field
            code.indent()
            for i,enum in enumerate(self.enums.itervalues()):
                code('  case $i:')
                code('    return ${{self.c_ident}}_${{enum.ident}};')
            code.dedent()

            # Trailer
            code('''
      default:
        panic("Invalid range for type ${{self.c_ident}}");
    }
}

/** \\brief The return value indicates the number of components created
 * before a particular machine\'s components
 *
 * \\return the base number of components for each machine
 */
int
${{self.c_ident}}_base_number(const ${{self.c_ident}}& obj)
{
    int base = 0;
    switch(obj) {
''')

            # For each field
            code.indent()
            code('  case ${{self.c_ident}}_NUM:')
            for enum in reversed(list(self.enums.values())):
                # Check if there is a defined machine with this type
                if enum.primary:
                    code('    base += ${{enum.ident}}_Controller::getNumControllers();')
                else:
                    code('    base += 0;')
                code('    M5_FALLTHROUGH;')
                code('  case ${{self.c_ident}}_${{enum.ident}}:')
            code('    break;')
            code.dedent()

            code('''
      default:
        panic("Invalid range for type ${{self.c_ident}}");
    }

    return base;
}

/** \\brief returns the total number of components for each machine
 * \\return the total number of components for each machine
 */
int
${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj)
{
    switch(obj) {
''')

            # For each field
            for enum in self.enums.itervalues():
                code('case ${{self.c_ident}}_${{enum.ident}}:')
                if enum.primary:
                    code('return ${{enum.ident}}_Controller::getNumControllers();')
                else:
                    code('return 0;')

            # total num
            code('''
      case ${{self.c_ident}}_NUM:
      default:
        panic("Invalid range for type ${{self.c_ident}}");
    }
}
''')

            for enum in self.enums.itervalues():
                code('''

MachineID
get${{enum.ident}}MachineID(NodeID RubyNode)
{
      MachineID mach = {MachineType_${{enum.ident}}, RubyNode};
      return mach;
}
''')

        # Write the file
        code.write(path, "%s.cc" % self.c_ident)

__all__ = [ "Type" ]
