from ..exceptions import WQXException
from .SimpleContent import (
  MeasureQualifierCode,
  MeasureUnitCode,
  ResultMeasureValue
)
from typing import List, Union
from yattag import Doc

class Measure:
  """Identifies the value, associated units of measure, and qualifier for measuring the observation or analytical result value."""

  __resultMeasureValue: ResultMeasureValue
  __measureUnitCode: MeasureUnitCode
  __measureQualifierCode: List[MeasureQualifierCode]

  def __init__(self, o=None, *,
    resultMeasureValue:ResultMeasureValue = None,
    measureUnitCode:MeasureUnitCode = None,
    measureQualifierCode:List[MeasureQualifierCode] = []
  ):
    if isinstance(o, Measure):
      # Assign attributes from object without typechecking
      self.__resultMeasureValue = o.resultMeasureValue
      self.__measureUnitCode = o.measureUnitCode
      self.__measureQualifierCode = o.measureQualifierCode
    elif isinstance(o, dict):
      # Assign attributes from dictionary with typechecking
      self.__resultMeasureValue = o.get('resultMeasureValue', default = None)
      self.__measureUnitCode = o.get('measureUnitCode', default = None)
      self.__measureQualifierCode = o.get('measureQualifierCode', default = [])
    else:
      # Assign attributes from named keywords with typechecking
      self.__resultMeasureValue = resultMeasureValue
      self.__measureUnitCode = measureUnitCode
      self.__measureQualifierCode = measureQualifierCode

  @property
  def resultMeasureValue(self) -> ResultMeasureValue:
    return self.__resultMeasureValue
  @resultMeasureValue.setter
  def resultMeasureValue(self, val:ResultMeasureValue) -> None:
    self.__resultMeasureValue = None if val is None else ResultMeasureValue(val)

  @property
  def measureUnitCode(self) -> MeasureUnitCode:
    return self.__measureUnitCode
  @measureUnitCode.setter
  def measureUnitCode(self, val:MeasureUnitCode) -> None:
    self.__measureUnitCode = None if val is None else MeasureUnitCode(val)

  @property
  def measureQualifierCode(self) -> List[MeasureQualifierCode]:
    return self.__measureQualifierCode
  @measureQualifierCode.setter
  def measureQualifierCode(self, val:Union[MeasureQualifierCode,List[MeasureQualifierCode]]) -> None:
    if val is None:
      self.__measureQualifierCode = []
    elif isinstance(val, list):
      r:List[MeasureQualifierCode] = []
      for x in val:
        r.append(MeasureQualifierCode(x))
      self.__measureQualifierCode = r
    else:
      self.__measureQualifierCode = [MeasureQualifierCode(val)]

  def generateXML(self, name:str = 'Measure') -> str:
    doc = Doc()
    line = doc.line
    tag = doc.tag

    with tag(name):
      if self.__resultMeasureValue is not None:
        line('ResultMeasureValue', self.__resultMeasureValue)
      if self.__measureUnitCode is not None:
        line('MeasureUnitCode', self.__measureUnitCode)
      if len(self.__measureQualifierCode) > 6:
        raise WQXException("Attribute 'measureQualifierCode' must be a list of 0 to 6 MeasureQualifierCode objects.")
      for x in self.__measureQualifierCode:
        line('MeasureQualifierCode', x)

    return doc.getvalue()
