#
# 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 ExperimentState(object):
    CREATED = 0
    VALIDATED = 1
    SCHEDULED = 2
    LAUNCHED = 3
    EXECUTING = 4
    CANCELING = 5
    CANCELED = 6
    COMPLETED = 7
    FAILED = 8

    _VALUES_TO_NAMES = {
        0: "CREATED",
        1: "VALIDATED",
        2: "SCHEDULED",
        3: "LAUNCHED",
        4: "EXECUTING",
        5: "CANCELING",
        6: "CANCELED",
        7: "COMPLETED",
        8: "FAILED",
    }

    _NAMES_TO_VALUES = {
        "CREATED": 0,
        "VALIDATED": 1,
        "SCHEDULED": 2,
        "LAUNCHED": 3,
        "EXECUTING": 4,
        "CANCELING": 5,
        "CANCELED": 6,
        "COMPLETED": 7,
        "FAILED": 8,
    }


class TaskState(object):
    CREATED = 0
    EXECUTING = 1
    COMPLETED = 2
    FAILED = 3
    CANCELED = 4

    _VALUES_TO_NAMES = {
        0: "CREATED",
        1: "EXECUTING",
        2: "COMPLETED",
        3: "FAILED",
        4: "CANCELED",
    }

    _NAMES_TO_VALUES = {
        "CREATED": 0,
        "EXECUTING": 1,
        "COMPLETED": 2,
        "FAILED": 3,
        "CANCELED": 4,
    }


class ProcessState(object):
    CREATED = 0
    VALIDATED = 1
    STARTED = 2
    PRE_PROCESSING = 3
    CONFIGURING_WORKSPACE = 4
    INPUT_DATA_STAGING = 5
    EXECUTING = 6
    MONITORING = 7
    OUTPUT_DATA_STAGING = 8
    POST_PROCESSING = 9
    COMPLETED = 10
    FAILED = 11
    CANCELLING = 12
    CANCELED = 13

    _VALUES_TO_NAMES = {
        0: "CREATED",
        1: "VALIDATED",
        2: "STARTED",
        3: "PRE_PROCESSING",
        4: "CONFIGURING_WORKSPACE",
        5: "INPUT_DATA_STAGING",
        6: "EXECUTING",
        7: "MONITORING",
        8: "OUTPUT_DATA_STAGING",
        9: "POST_PROCESSING",
        10: "COMPLETED",
        11: "FAILED",
        12: "CANCELLING",
        13: "CANCELED",
    }

    _NAMES_TO_VALUES = {
        "CREATED": 0,
        "VALIDATED": 1,
        "STARTED": 2,
        "PRE_PROCESSING": 3,
        "CONFIGURING_WORKSPACE": 4,
        "INPUT_DATA_STAGING": 5,
        "EXECUTING": 6,
        "MONITORING": 7,
        "OUTPUT_DATA_STAGING": 8,
        "POST_PROCESSING": 9,
        "COMPLETED": 10,
        "FAILED": 11,
        "CANCELLING": 12,
        "CANCELED": 13,
    }


class JobState(object):
    SUBMITTED = 0
    QUEUED = 1
    ACTIVE = 2
    COMPLETE = 3
    CANCELED = 4
    FAILED = 5
    SUSPENDED = 6
    UNKNOWN = 7

    _VALUES_TO_NAMES = {
        0: "SUBMITTED",
        1: "QUEUED",
        2: "ACTIVE",
        3: "COMPLETE",
        4: "CANCELED",
        5: "FAILED",
        6: "SUSPENDED",
        7: "UNKNOWN",
    }

    _NAMES_TO_VALUES = {
        "SUBMITTED": 0,
        "QUEUED": 1,
        "ACTIVE": 2,
        "COMPLETE": 3,
        "CANCELED": 4,
        "FAILED": 5,
        "SUSPENDED": 6,
        "UNKNOWN": 7,
    }


class ExperimentStatus(object):
    """
    Status: A generic status object.

    state:
      State .

    timeOfStateChange:
      time the status was last updated.

    reason:
      User friendly reason on how the state is inferred.


    Attributes:
     - state
     - timeOfStateChange
     - reason
    """

    thrift_spec = (
        None,  # 0
        (1, TType.I32, 'state', None, None, ),  # 1
        (2, TType.I64, 'timeOfStateChange', None, None, ),  # 2
        (3, TType.STRING, 'reason', 'UTF8', None, ),  # 3
    )

    def __init__(self, state=None, timeOfStateChange=None, reason=None,):
        self.state = state
        self.timeOfStateChange = timeOfStateChange
        self.reason = reason

    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.state = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I64:
                    self.timeOfStateChange = iprot.readI64()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.reason = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                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('ExperimentStatus')
        if self.state is not None:
            oprot.writeFieldBegin('state', TType.I32, 1)
            oprot.writeI32(self.state)
            oprot.writeFieldEnd()
        if self.timeOfStateChange is not None:
            oprot.writeFieldBegin('timeOfStateChange', TType.I64, 2)
            oprot.writeI64(self.timeOfStateChange)
            oprot.writeFieldEnd()
        if self.reason is not None:
            oprot.writeFieldBegin('reason', TType.STRING, 3)
            oprot.writeString(self.reason.encode('utf-8') if sys.version_info[0] == 2 else self.reason)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.state is None:
            raise TProtocolException(message='Required field state is unset!')
        return

    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)


class ProcessStatus(object):
    """
    Attributes:
     - state
     - timeOfStateChange
     - reason
    """

    thrift_spec = (
        None,  # 0
        (1, TType.I32, 'state', None, None, ),  # 1
        (2, TType.I64, 'timeOfStateChange', None, None, ),  # 2
        (3, TType.STRING, 'reason', 'UTF8', None, ),  # 3
    )

    def __init__(self, state=None, timeOfStateChange=None, reason=None,):
        self.state = state
        self.timeOfStateChange = timeOfStateChange
        self.reason = reason

    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.state = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I64:
                    self.timeOfStateChange = iprot.readI64()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.reason = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                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('ProcessStatus')
        if self.state is not None:
            oprot.writeFieldBegin('state', TType.I32, 1)
            oprot.writeI32(self.state)
            oprot.writeFieldEnd()
        if self.timeOfStateChange is not None:
            oprot.writeFieldBegin('timeOfStateChange', TType.I64, 2)
            oprot.writeI64(self.timeOfStateChange)
            oprot.writeFieldEnd()
        if self.reason is not None:
            oprot.writeFieldBegin('reason', TType.STRING, 3)
            oprot.writeString(self.reason.encode('utf-8') if sys.version_info[0] == 2 else self.reason)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.state is None:
            raise TProtocolException(message='Required field state is unset!')
        return

    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)


class TaskStatus(object):
    """
    Attributes:
     - state
     - timeOfStateChange
     - reason
    """

    thrift_spec = (
        None,  # 0
        (1, TType.I32, 'state', None, None, ),  # 1
        (2, TType.I64, 'timeOfStateChange', None, None, ),  # 2
        (3, TType.STRING, 'reason', 'UTF8', None, ),  # 3
    )

    def __init__(self, state=None, timeOfStateChange=None, reason=None,):
        self.state = state
        self.timeOfStateChange = timeOfStateChange
        self.reason = reason

    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.state = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I64:
                    self.timeOfStateChange = iprot.readI64()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.reason = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                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('TaskStatus')
        if self.state is not None:
            oprot.writeFieldBegin('state', TType.I32, 1)
            oprot.writeI32(self.state)
            oprot.writeFieldEnd()
        if self.timeOfStateChange is not None:
            oprot.writeFieldBegin('timeOfStateChange', TType.I64, 2)
            oprot.writeI64(self.timeOfStateChange)
            oprot.writeFieldEnd()
        if self.reason is not None:
            oprot.writeFieldBegin('reason', TType.STRING, 3)
            oprot.writeString(self.reason.encode('utf-8') if sys.version_info[0] == 2 else self.reason)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.state is None:
            raise TProtocolException(message='Required field state is unset!')
        return

    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)


class JobStatus(object):
    """
    Attributes:
     - jobState
     - timeOfStateChange
     - reason
    """

    thrift_spec = (
        None,  # 0
        (1, TType.I32, 'jobState', None, None, ),  # 1
        (2, TType.I64, 'timeOfStateChange', None, None, ),  # 2
        (3, TType.STRING, 'reason', 'UTF8', None, ),  # 3
    )

    def __init__(self, jobState=None, timeOfStateChange=None, reason=None,):
        self.jobState = jobState
        self.timeOfStateChange = timeOfStateChange
        self.reason = reason

    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.jobState = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I64:
                    self.timeOfStateChange = iprot.readI64()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.reason = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                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('JobStatus')
        if self.jobState is not None:
            oprot.writeFieldBegin('jobState', TType.I32, 1)
            oprot.writeI32(self.jobState)
            oprot.writeFieldEnd()
        if self.timeOfStateChange is not None:
            oprot.writeFieldBegin('timeOfStateChange', TType.I64, 2)
            oprot.writeI64(self.timeOfStateChange)
            oprot.writeFieldEnd()
        if self.reason is not None:
            oprot.writeFieldBegin('reason', TType.STRING, 3)
            oprot.writeString(self.reason.encode('utf-8') if sys.version_info[0] == 2 else self.reason)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.jobState is None:
            raise TProtocolException(message='Required field jobState is unset!')
        return

    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)


class QueueStatusModel(object):
    """
    Attributes:
     - hostName
     - queueName
     - queueUp
     - runningJobs
     - queuedJobs
     - time
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'hostName', 'UTF8', None, ),  # 1
        (2, TType.STRING, 'queueName', 'UTF8', None, ),  # 2
        (3, TType.BOOL, 'queueUp', None, None, ),  # 3
        (4, TType.I32, 'runningJobs', None, None, ),  # 4
        (5, TType.I32, 'queuedJobs', None, None, ),  # 5
        (6, TType.I64, 'time', None, None, ),  # 6
    )

    def __init__(self, hostName=None, queueName=None, queueUp=None, runningJobs=None, queuedJobs=None, time=None,):
        self.hostName = hostName
        self.queueName = queueName
        self.queueUp = queueUp
        self.runningJobs = runningJobs
        self.queuedJobs = queuedJobs
        self.time = time

    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.STRING:
                    self.hostName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.queueName = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.BOOL:
                    self.queueUp = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.I32:
                    self.runningJobs = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 5:
                if ftype == TType.I32:
                    self.queuedJobs = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 6:
                if ftype == TType.I64:
                    self.time = iprot.readI64()
                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('QueueStatusModel')
        if self.hostName is not None:
            oprot.writeFieldBegin('hostName', TType.STRING, 1)
            oprot.writeString(self.hostName.encode('utf-8') if sys.version_info[0] == 2 else self.hostName)
            oprot.writeFieldEnd()
        if self.queueName is not None:
            oprot.writeFieldBegin('queueName', TType.STRING, 2)
            oprot.writeString(self.queueName.encode('utf-8') if sys.version_info[0] == 2 else self.queueName)
            oprot.writeFieldEnd()
        if self.queueUp is not None:
            oprot.writeFieldBegin('queueUp', TType.BOOL, 3)
            oprot.writeBool(self.queueUp)
            oprot.writeFieldEnd()
        if self.runningJobs is not None:
            oprot.writeFieldBegin('runningJobs', TType.I32, 4)
            oprot.writeI32(self.runningJobs)
            oprot.writeFieldEnd()
        if self.queuedJobs is not None:
            oprot.writeFieldBegin('queuedJobs', TType.I32, 5)
            oprot.writeI32(self.queuedJobs)
            oprot.writeFieldEnd()
        if self.time is not None:
            oprot.writeFieldBegin('time', TType.I64, 6)
            oprot.writeI64(self.time)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.hostName is None:
            raise TProtocolException(message='Required field hostName is unset!')
        if self.queueName is None:
            raise TProtocolException(message='Required field queueName is unset!')
        if self.queueUp is None:
            raise TProtocolException(message='Required field queueUp is unset!')
        if self.runningJobs is None:
            raise TProtocolException(message='Required field runningJobs is unset!')
        if self.queuedJobs is None:
            raise TProtocolException(message='Required field queuedJobs is unset!')
        if self.time is None:
            raise TProtocolException(message='Required field time is unset!')
        return

    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)
