<?php
namespace CorpusParole\Libraries\Transcript;

use CorpusParole\Models\Document;

use EasyRdf\Literal;
use DateTime;


abstract class TranscriptConverterBase implements TranscriptConverterInterface {

    public function __construct(Document $document, $source, $creationDate = null) {
        $this->resJSON = [];
        $this->document = $document;

        $this->source = new \DOMDocument();
        $this->source->loadXML($source, LIBXML_NOCDATA|LIBXML_NOBLANKS);

        $this->creationDate = $creationDate;
        $this->mediaRefId = null;
        if(is_null($this->creationDate)) {
            $this->creationDate = (new DateTime())->format(DateTime::ATOM);
        }
    }

    public function addHeaderMeta() {

        $this->resJSON['format'] = 'http://advene.org/ns/cinelab/';
        $this->resJSON["@context"] = [
            "dc" =>  "http://purl.org/dc/elements/1.1/",
            "corpus" => "http://corpusdelaparole.huma-num.fr/ns/corpus#"
        ];

        $title = $this->getSourceTitle();
        if(is_null($title)) {
            $docTitle = $this->document->getTitle();
            if($docTitle instanceof Literal) {
                $titleLanguage = $docTitle->getLang();
                $title = $titleLanguage?[$titleLanguage => $docTitle->getValue()]:$docTitle->getValue();
            }
            elseif(!is_null($docTitle)) {
                $title = (string)$docTitle;
            }
        }

        $this->title = null;

        if(is_string($title)) {
            $this->title = $title;
        }
        elseif(is_array($title) && count($title) == 1) {
            $this->title = [ "@language" => key($title),  "@value" => current($title)];
        }
        elseif(is_array($title)) {
            $this->title = array_reduce(array_keys($title),function($res, $k) use ($title) {
                array_push($res, ["@language" => $k, "@value" => $title[$k]]);
                return $res;
            }, []);
        }

        $this->resJSON['meta'] = [
            'dc:creator' => config('corpusparole.transcript_default_creator'),
            'dc:contributor' => config('corpusparole.transcript_default_creator'),
            'dc:created' => $this->creationDate,
            'dc:modified' => $this->creationDate,
            'dc:title' => $this->title
        ];
    }

    // get document title
    public function getSourceTitle() {
        return null;
    }

    // add media
    public function buildMedias() {

        $medias = [];

        $i = 1;
        foreach($this->document->getMediaArray() as $documentMedia)
        {

            $mId = $this->document->getId()."_m$i";
            $i++;
            if(is_null($this->mediaRefId) || $documentMedia->isMaster()) {
                $this->mediaRefId = $mId;
            }
            array_push($medias, [
                'id' => $mId,
                'origin' => 0,
                'unit' => 'ms',
                'url' => $documentMedia->getUrl(),
                'meta' => [
                    'dc:duration' => $documentMedia->getExtentMs(),
                    'dc:title' => $this->title,
                    'dc:format' => $documentMedia->getFormat(),
                    'corpus:master' =>  filter_var($documentMedia->isMaster(), FILTER_VALIDATE_BOOLEAN)
                ]
            ]);
        }

        return $medias;

    }

    public function getMediaRefId() {
        return $this->mediaRefId;
    }

    public abstract function parseSource();

    // add resources
    public function buildResources() {
        return [];
    }

    // add lists
    public function buildLists() {
        return [];
    }

    // add annotation types
    public function buildAnnotationTypes() {
        return [];
    }

    // add annotations
    public abstract function buildAnnotations();

    protected function buildTextvalue($text, $language) {
        if(empty($language)) {
            return $text;
        } else {
            return ['@value' => $text, '@language' => $language];
        }
    }

    /**
     * Convert xml to json.
     * return an PHP array ready for serialization
     */
    function convertToJson() {

        $this->addHeaderMeta();

        $this->resJSON['medias'] = $this->buildMedias();

        $this->parseSource();

        $this->resJSON['resources'] = $this->buildResources();
        $this->resJSON['lists'] = $this->buildLists();
        $this->resJSON['annotation-types'] = $this->buildAnnotationTypes();
        $this->resJSON['annotations'] = $this->buildAnnotations();

        return $this->resJSON;
    }

}
