#
# Autogenerated by Thrift Compiler (0.10.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py
#

from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
from thrift.protocol.TProtocol import TProtocolException
import sys

from thrift.transport import TTransport


class pltfm_pm_port_speed_t(object):
    BF_SPEED_NONE = 0
    BF_SPEED_1G = 1
    BF_SPEED_10G = 2
    BF_SPEED_25G = 3
    BF_SPEED_40G = 4
    BF_SPEED_40G_NB = 5
    BF_SPEED_50G = 6
    BF_SPEED_100G = 7
    BF_SPEED_40G_NON_BREAKABLE = 8

    _VALUES_TO_NAMES = {
        0: "BF_SPEED_NONE",
        1: "BF_SPEED_1G",
        2: "BF_SPEED_10G",
        3: "BF_SPEED_25G",
        4: "BF_SPEED_40G",
        5: "BF_SPEED_40G_NB",
        6: "BF_SPEED_50G",
        7: "BF_SPEED_100G",
        8: "BF_SPEED_40G_NON_BREAKABLE",
    }

    _NAMES_TO_VALUES = {
        "BF_SPEED_NONE": 0,
        "BF_SPEED_1G": 1,
        "BF_SPEED_10G": 2,
        "BF_SPEED_25G": 3,
        "BF_SPEED_40G": 4,
        "BF_SPEED_40G_NB": 5,
        "BF_SPEED_50G": 6,
        "BF_SPEED_100G": 7,
        "BF_SPEED_40G_NON_BREAKABLE": 8,
    }


class pltfm_pm_fec_type_t(object):
    BF_FEC_TYP_NONE = 0
    BF_FEC_TYP_FIRECODE = 1
    BF_FEC_TYP_REED_SOLOMON = 2

    _VALUES_TO_NAMES = {
        0: "BF_FEC_TYP_NONE",
        1: "BF_FEC_TYP_FIRECODE",
        2: "BF_FEC_TYP_REED_SOLOMON",
    }

    _NAMES_TO_VALUES = {
        "BF_FEC_TYP_NONE": 0,
        "BF_FEC_TYP_FIRECODE": 1,
        "BF_FEC_TYP_REED_SOLOMON": 2,
    }


class pltfm_pm_oper_status_t(object):
    DOWN = 0
    UP = 1

    _VALUES_TO_NAMES = {
        0: "DOWN",
        1: "UP",
    }

    _NAMES_TO_VALUES = {
        "DOWN": 0,
        "UP": 1,
    }


class pltfm_pm_board_type_t(object):
    BF_PLTFM_BD_ID_MAVERICKS_P0A = 564
    BF_PLTFM_BD_ID_MAVERICKS_P0B = 4660
    BF_PLTFM_BD_ID_MONTARA_P0A = 8756
    BF_PLTFM_BD_ID_MONTARA_P0B = 12852
    BF_PLTFM_BD_ID_MAVERICKS_P0B_EMU = 16948
    BF_PLTFM_BD_ID_UNKNOWN = 0
    XFFFF = 1

    _VALUES_TO_NAMES = {
        564: "BF_PLTFM_BD_ID_MAVERICKS_P0A",
        4660: "BF_PLTFM_BD_ID_MAVERICKS_P0B",
        8756: "BF_PLTFM_BD_ID_MONTARA_P0A",
        12852: "BF_PLTFM_BD_ID_MONTARA_P0B",
        16948: "BF_PLTFM_BD_ID_MAVERICKS_P0B_EMU",
        0: "BF_PLTFM_BD_ID_UNKNOWN",
        1: "XFFFF",
    }

    _NAMES_TO_VALUES = {
        "BF_PLTFM_BD_ID_MAVERICKS_P0A": 564,
        "BF_PLTFM_BD_ID_MAVERICKS_P0B": 4660,
        "BF_PLTFM_BD_ID_MONTARA_P0A": 8756,
        "BF_PLTFM_BD_ID_MONTARA_P0B": 12852,
        "BF_PLTFM_BD_ID_MAVERICKS_P0B_EMU": 16948,
        "BF_PLTFM_BD_ID_UNKNOWN": 0,
        "XFFFF": 1,
    }


class InvalidPltfmPmOperation(TException):
    """
    Attributes:
     - code
    """

    thrift_spec = (
        None,  # 0
        (1, TType.I32, 'code', None, None, ),  # 1
    )

    def __init__(self, code=None,):
        self.code = code

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, (self.__class__, self.thrift_spec))
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.I32:
                    self.code = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, (self.__class__, self.thrift_spec)))
            return
        oprot.writeStructBegin('InvalidPltfmPmOperation')
        if self.code is not None:
            oprot.writeFieldBegin('code', TType.I32, 1)
            oprot.writeI32(self.code)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __str__(self):
        return repr(self)

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
