<?php

namespace Application\Service\Extension\Xml;
use Application\Service\Exceptions\InvalidArgumentException;

/**
 * xml解析器
 */
class XmlParser
{
    private ?object $xmlContent = null;

    public function __construct($xmlContent)
    {
        $this->xmlContent = simplexml_load_string($xmlContent, 'SimpleXMLElement', LIBXML_NOCDATA);

        if (!$this->xmlContent) {
            throw new InvalidArgumentException('xml解析失败');
        }
    }

    /**
     * <ODM/>
     * @return string
     */
    public function getRootNode($attribute = null)
    {
        if ($attribute) {
            return (string)$this->xmlContent->attributes()->$attribute;
        }
        return $this->xmlContent;
    }

    /**
     * <ODM>
     *      <ClinicalData></ClinicalData>
     * </ODM>
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    private function getClinicalData($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getClinicalData()->attributes()->$attribute;
        }

        return $this->getRootNode()->ClinicalData;
    }

    /**
     * <ODM>
     *      <ClinicalData>
     *          <SubjectData></SubjectData>
     *      </ClinicalData>
     * </ODM>
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    private function getSubjectData($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getSubjectData()->attributes()->$attribute;
        }

        return $this->getClinicalData()->SubjectData;
    }

    /**
     * <ODM>
     *      <ClinicalData>
     *          <SubjectData>
     *              <SiteRef/>
     *          </SubjectData>
     *      </ClinicalData>
     * </ODM>
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    public function getSiteRef($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getSiteRef()->attributes()->$attribute;
        }

        return $this->getSubjectData()->SiteRef;
    }

    /**
     * <ODM>
     *      <ClinicalData>
     *          <SubjectData>
     *              <SiteRef />
     *              <StudyEventData />
     *          </SubjectData>
     *      </ClinicalData>
     * </ODM>
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    private function getStudyEventData($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getStudyEventData()->attributes()->$attribute;
        }

        return $this->getSubjectData()->StudyEventData;
    }

    /**
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    private function getFormData($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getFormData()->attributes()->$attribute;
        }

        return $this->getStudyEventData()->FormData;
    }

    /**
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    private function getItemGroupData($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getItemGroupData()->attributes()->$attribute;
        }

        return $this->getFormData()->ItemGroupData;
    }

    /**
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    public function getDiscrepancyNotes($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getDiscrepancyNotes()->attributes()->$attribute;
        }

        return $this->getItemGroupData()->DiscrepancyNotes;
    }

    /**
     * @param null $attribute
     * @return string|\SimpleXMLElement
     */
    public function getDetailedNote($attribute = null)
    {
        if ($attribute) {
            return (string)$this->getDetailedNote()->attributes()->$attribute;
        }

        return $this->getDiscrepancyNotes()->DetailedNote;
    }


    /**
     * <ODM CreationDateTime/>
     * @return string
     */
    public function getCreationDateTime(): string
    {
        return $this->getRootNode('CreationDateTime');
    }

    /**
     * <ODM FileType/>
     * @return string
     */
    public function getFileType(): string
    {
        return $this->getRootNode('FileType');
    }

    /**
     * <ODM FileOID/>
     * @return string
     */
    public function getFileOid(): string
    {
        return (string)$this->getRootNode('FileOID');
    }

    /**
     * <ClinicalData StudyOID>
     * @return \SimpleXMLElement|string
     */
    public function getStudyOID()
    {
        return $this->getClinicalData('StudyOID');
    }

    /**
     * 受试者编号
     * <ClinicalData>
     *      <SubjectData SubjectKey="toom2"></SubjectData>
     * </ClinicalData>
     * @return \SimpleXMLElement|string
     */
    public function getSubjectKey()
    {
        return $this->getSubjectData('SubjectKey');
    }

    /**
     * 中心id
     * <ClinicalData>
     *      <SubjectData>
     *          <SiteRef LocationOID="100">
     *      </SubjectData>
     * </ClinicalData>
     * @return \SimpleXMLElement|string
     */
    public function getLocationOID()
    {
        return $this->getSiteRef('LocationOID');
    }

    /**
     * 检查点id
     * <ClinicalData>
     *      <SubjectData>
     *          <StudyEventData StudyEventOID="100">
     *      </SubjectData>
     * </ClinicalData>
     * @return \SimpleXMLElement|string
     */
    public function getStudyEventOID()
    {
        return $this->getStudyEventData('StudyEventOID');
    }

}