<?php

use Mockery as m;

use CorpusParole\Models\Document;
use CorpusParole\Libraries\Transcript\LacitoTranscriptConverter;


/**
 *
 */
class LacitoTranscriptConverterTest extends TestCase {
    const TEST_DOC_BASE = "crdo-UVE_MOCIKA";

    public function setUp() {
        parent::setup();
        $graphContent = sprintf(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . self::TEST_DOC_BASE.".ttl"), config('corpusparole.corpus_doc_id_base_uri'), config('corpusparole.corpus_id_scheme'));
        $this->graph = new EasyRdf\Graph(config('corpusparole.corpus_doc_id_base_uri')."crdo-UVE_MOCIKA_SOUND", $graphContent);
        $this->doc = new Document(config('corpusparole.corpus_doc_id_base_uri')."crdo-UVE_MOCIKA_SOUND", $this->graph);

        $this->transcriptSource = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . self::TEST_DOC_BASE.".xml");

        $this->transcriptSourceSpeaker = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR ."crdo-FRA_PK_IV_10.xml");

        $this->transcriptSourceNoContent = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR ."crdo-FSL-CUC023.xml");

    }

    public function getMockConverter(...$contructorArgs) {
        return new LacitoTranscriptConverter(...$contructorArgs);
    }


    public function testConstructor() {
        $converter = $this->getMockConverter($this->doc, $this->transcriptSource);
        $json = $converter->convertToJson();
        $this->assertNotnull($json);
    }

    public function testGetSourceTitle() {
        $converter = $this->getMockConverter($this->doc, $this->transcriptSource);
        $titles = $converter->getSourceTitle();

        $this->assertEquals(['en' => 'The two hermit crabs and the coconut crab', 'fr' => "Les deux bernard-l'hermite et le crabe de cocotier"], $titles, "Titles must come from the xml file");
    }

    public function testBuildAnnotations() {
        $converter = $this->getMockConverter($this->doc, $this->transcriptSource);
        $annotations = $converter->buildAnnotations();

        $this->assertCount(32, $annotations, "Must have 32 annotation");
        foreach($annotations as $i => $a) {
            $this->assertArrayHasKey('begin', $a, "Must have begin key");
            $this->assertArrayHasKey('end', $a, "Must have begin key");
            $this->assertTrue($a['begin']<$a['end'], "Begin is < to endP");
            $this->assertEquals($this->doc->getId()."_a".sprintf("%03s",($i+1)), $a['id']);
            $this->assertEquals($converter->getMediaRefId(), $a['media']);
            $this->assertArrayHasKey('content', $a, "must have content");
            $this->assertTrue(is_array($a['content']));
            $this->assertArrayHasKey('mimetype', $a['content']);
            $this->assertEquals('application/json', $a['content']['mimetype']);
            $this->assertArrayHasKey('data', $a['content']);
            $this->assertTrue(is_array($a['content']['data']));
        }
    }


    public function testBuildAnnotationsContent() {
        $converter = $this->getMockConverter($this->doc, $this->transcriptSource);
        $annotations = $converter->buildAnnotations();

        foreach($annotations as $i => $a) {
            $data = $a['content']['data'];
            $this->assertArrayNotHasKey('speaker', $data, "No spreaker in data for this source");
            $this->assertArrayHasKey('content', $data, "data has content");
            $this->assertNotEmpty($data['content'], "content not empty");
            $this->arrayHasKey('transl', $data, 'data has translation');
            $this->assertTrue(is_array($data['transl']), 'data transl is array');
            $this->assertArrayHasKey('@value', $data['transl'], 'dats transl has @value key');
            $this->assertArrayHasKey('@language', $data['transl'], 'dats transl has @language key');

            $this->assertArrayHasKey('words', $data, 'data has words');
            $this->assertNotEmpty($data['words'], "words are not empty");
            foreach($data['words'] as $w) {
                $this->assertTrue(is_array($w), 'words are array');
                $this->assertArrayHasKey('content', $w, "words have content");
                $this->assertNotEmpty($w['content'], "words have non empty content");
                $this->assertArrayHasKey('transl', $w, "words have transl");
                $this->assertArrayHasKey('@value', $w['transl'], 'words transl has @value key');
                $this->assertArrayHasKey('@language', $w['transl'], 'words transl has @language key');
            }
        }
    }


    public function testBuildAnnotationsSpeaker() {
        $converter = $this->getMockConverter($this->doc, $this->transcriptSourceSpeaker);
        $annotations = $converter->buildAnnotations();
        foreach($annotations as $i => $a) {
            $data = $a['content']['data'];
            $this->assertArrayHasKey('speaker', $data, 'annotation must have speaker');
            $this->assertArrayNotHasKey('words', $data, 'No words in data here');
        }
    }

    public function testBuildAnnotationsSpeakerTitle() {
        $converter = $this->getMockConverter($this->doc, $this->transcriptSourceSpeaker);
        $this->assertNull($converter->getSourceTitle(), "Title is not on source");
    }

    public function testBuildAnnotationsNoContent() {
        $converter = $this->getMockConverter($this->doc, $this->transcriptSourceNoContent);
        $annotations = $converter->buildAnnotations();
        foreach($annotations as $i => $a) {
            $data = $a['content']['data'];
            $this->assertArrayNotHasKey('words', $data, 'No words in data here');
            $this->assertArrayNotHasKey('content', $data, 'No content in data here');
            $this->arrayHasKey('transl', $data, 'data has translation');
            $this->assertTrue(is_array($data['transl']), 'data transl is array');
            $this->assertArrayHasKey('@value', $data['transl'], 'dats transl has @value key');
            $this->assertArrayHasKey('@language', $data['transl'], 'dats transl has @language key');
        }
    }


    public function tearDown() {
        m::close();
    }

}
