from enum import Enum
from yattag import Doc, indent
from .wqx_v3_0.WQX import WQX
from .wqx_v3_0.WQX_Update_Identifiers import WQXUpdateIdentifiers
from .wqx_v3_0.WQX_Delete import WQXDelete
from .exceptions import WQXException

class OperationType( Enum ):
  UPDATE_INSERT = 'Update-Insert'
  DELETE = 'Delete'

class Payload:
  """The Payload section of the document contains the WQX data."""

  __operation: OperationType
  __wqx: WQX
  __wqxUpdateIdentifiers: WQXUpdateIdentifiers
  __wqxDelete: WQXDelete

  UPDATE_INSERT = OperationType.UPDATE_INSERT
  DELETE = OperationType.DELETE

  def __init__(self, o=None, *,
    operation = None,
    wqx = None,
    wqxUpdateIdentifiers = None,
    wqxDelete = None
  ):
    if isinstance(o, Payload):
      # Assign attributes from other Payload without typechecking
      self.__operation = o.operation
      self.__wqx = o.wqx
      self.__wqxUpdateIdentifiers = o.wqxUpdateIdentifiers
      self.__wqxDelete = o.wqxDelete
    elif isinstance(o, dict):
      # Assign attributes from dictionary with typechecking
      self.operation = o.get('operation', default = None)
      self.wqx = o.get('wqx', default = None)
      self.wqxUpdateIdentifiers = o.get('wqxUpdateIdentifiers', default = None)
      self.wqxDelete = o.get('wqxDelete', default = None)
    else:
      # Assign attributes from named keywords with typechecking
      self.operation = operation
      self.wqx = wqx
      self.wqxUpdateIdentifiers = wqxUpdateIdentifiers
      self.wqxDelete = wqxDelete

  @property
  def operation(self) -> OperationType:
    return self.__operation
  @operation.setter
  def operation(self, val:OperationType) -> None:
    self.__operation = None if val is None else OperationType(val)

  @property
  def wqx(self) -> WQX:
    return self.__wqx
  @wqx.setter
  def wqx(self, val:WQX) -> None:
    if val is not None and not isinstance(val, WQX):
      raise WQXException("Attribute 'wqx' must be a WQX object, if provided.")
    self.__wqx = None if val is None else WQX(val)

  @property
  def wqxUpdateIdentifiers(self) -> WQXUpdateIdentifiers:
    return self.__wqxUpdateIdentifiers
  @wqxUpdateIdentifiers.setter
  def wqxUpdateIdentifiers(self, val:WQXUpdateIdentifiers) -> None:
    if val is not None and not isinstance(val, WQXUpdateIdentifiers):
      raise WQXException("Attribute 'wqxUpdateIdentifiers' must be a WQXUpdateIdentifiers object, if provided.")
    self.__wqxUpdateIdentifiers = None if val is None else WQXUpdateIdentifiers(val)

  @property
  def wqxDelete(self) -> WQXDelete:
    return self.__wqxDelete
  @wqxDelete.setter
  def wqxDelete(self, val:WQXDelete) -> None:
    if val is not None and not isinstance(val, WQXDelete):
      raise WQXException("Attribute 'wqxDelete' must be a WQXDelete object, if provided.")
    self.__wqxDelete = None if val is None else WQXDelete(val)

  def generateXML(self, name:str = 'Payload') -> str:
    doc = Doc()
    asis = doc.asis

    if self.__operation is None:
      raise WQXException("Attribute 'operation' is required.")
    with doc.tag(name, ('Operation', self.__operation.value)):
      if self.__operation == OperationType.UPDATE_INSERT:
        if self.__wqxDelete is not None:
          raise WQXException("Attribute 'wqxDelete' must be set to None for 'Update-Insert' operation.")
        if self.__wqx is None and self.__wqxUpdateIdentifiers is None:
          raise WQXException("One of attributes 'wqx' or 'wqxUpdateIdentifiers' are required for 'Update-Insert' operation.")
        elif self.__wqx is not None and self.__wqxUpdateIdentifiers is not None:
          raise WQXException("One of attributes 'wqx' or 'wqxUpdateIdentifiers' must be set to None for 'Update-Insert' operation.")
        elif self.__wqx is None and self.__wqxUpdateIdentifiers is None:
          raise WQXException("One of attributes 'wqx' or 'wqxUpdateIdentifiers' must be set for 'Update-Insert' operation.")
        elif self.__wqx is not None and self.__wqxUpdateIdentifiers is None:
          asis(self.__wqx.generateXML('WQX'))
        elif self.__wqxUpdateIdentifiers is not None and self.__wqx is None:
          asis(self.__wqxUpdateIdentifiers.generateXML('WQXUpdateIdentifiers'))
      elif self.__operation == OperationType.DELETE:
        if self.__wqx is not None:
          raise WQXException("Attribute 'wqx' must be set to None for 'Delete' operation.")
        if self.__wqxUpdateIdentifiers is not None:
          raise WQXException("Attribute 'wqxUpdateIdentifiers' must be set to None for 'Delete' operation.")
        if self.__wqxDelete is None:
          raise WQXException("Attribute 'wqxDelete' is required for 'Delete' operation.")
        asis(self.__wqxDelete.generateXML('WQXDelete'))
      else:
        raise WQXException("Attribute 'operation' must be either 'Update-Insert' or 'Delete'.")

    return doc.getvalue()
