#
# 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
import airavata.model.commons.ttypes

from thrift.transport import TTransport


class ResourceType(object):
    PROJECT = 0
    EXPERIMENT = 1
    DATA = 2
    APPLICATION_DEPLOYMENT = 3
    GROUP_RESOURCE_PROFILE = 4
    CREDENTIAL_TOKEN = 5
    OTHER = 6

    _VALUES_TO_NAMES = {
        0: "PROJECT",
        1: "EXPERIMENT",
        2: "DATA",
        3: "APPLICATION_DEPLOYMENT",
        4: "GROUP_RESOURCE_PROFILE",
        5: "CREDENTIAL_TOKEN",
        6: "OTHER",
    }

    _NAMES_TO_VALUES = {
        "PROJECT": 0,
        "EXPERIMENT": 1,
        "DATA": 2,
        "APPLICATION_DEPLOYMENT": 3,
        "GROUP_RESOURCE_PROFILE": 4,
        "CREDENTIAL_TOKEN": 5,
        "OTHER": 6,
    }


class ResourcePermissionType(object):
    WRITE = 0
    READ = 1
    OWNER = 2
    MANAGE_SHARING = 3

    _VALUES_TO_NAMES = {
        0: "WRITE",
        1: "READ",
        2: "OWNER",
        3: "MANAGE_SHARING",
    }

    _NAMES_TO_VALUES = {
        "WRITE": 0,
        "READ": 1,
        "OWNER": 2,
        "MANAGE_SHARING": 3,
    }


class GroupModel(object):
    """
    Attributes:
     - id
     - name
     - ownerId
     - description
     - members
     - admins: Note: each admin must also be a member of the group.
    """

    thrift_spec = (
        None,  # 0
        (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
        (2, TType.STRING, 'name', 'UTF8', None, ),  # 2
        (3, TType.STRING, 'ownerId', 'UTF8', None, ),  # 3
        (4, TType.STRING, 'description', 'UTF8', None, ),  # 4
        (5, TType.LIST, 'members', (TType.STRING, 'UTF8', False), None, ),  # 5
        (6, TType.LIST, 'admins', (TType.STRING, 'UTF8', False), None, ),  # 6
    )

    def __init__(self, id=None, name=None, ownerId=None, description=None, members=None, admins=None,):
        self.id = id
        self.name = name
        self.ownerId = ownerId
        self.description = description
        self.members = members
        self.admins = admins

    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.id = 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.name = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.ownerId = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRING:
                    self.description = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 5:
                if ftype == TType.LIST:
                    self.members = []
                    (_etype3, _size0) = iprot.readListBegin()
                    for _i4 in range(_size0):
                        _elem5 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                        self.members.append(_elem5)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 6:
                if ftype == TType.LIST:
                    self.admins = []
                    (_etype9, _size6) = iprot.readListBegin()
                    for _i10 in range(_size6):
                        _elem11 = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                        self.admins.append(_elem11)
                    iprot.readListEnd()
                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('GroupModel')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 2)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.ownerId is not None:
            oprot.writeFieldBegin('ownerId', TType.STRING, 3)
            oprot.writeString(self.ownerId.encode('utf-8') if sys.version_info[0] == 2 else self.ownerId)
            oprot.writeFieldEnd()
        if self.description is not None:
            oprot.writeFieldBegin('description', TType.STRING, 4)
            oprot.writeString(self.description.encode('utf-8') if sys.version_info[0] == 2 else self.description)
            oprot.writeFieldEnd()
        if self.members is not None:
            oprot.writeFieldBegin('members', TType.LIST, 5)
            oprot.writeListBegin(TType.STRING, len(self.members))
            for iter12 in self.members:
                oprot.writeString(iter12.encode('utf-8') if sys.version_info[0] == 2 else iter12)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.admins is not None:
            oprot.writeFieldBegin('admins', TType.LIST, 6)
            oprot.writeListBegin(TType.STRING, len(self.admins))
            for iter13 in self.admins:
                oprot.writeString(iter13.encode('utf-8') if sys.version_info[0] == 2 else iter13)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        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)
