<?php

use CorpusParole\Models\GeoResource;
use CorpusParole\Models\Document;
use CorpusParole\Libraries\CocoonUtils;

/**
 *
 */
class GeoResourceTest extends TestCase {

    const TEST_DOCS = [
        "LOC1" =>  __DIR__.'/files/GeoResourceTest/loc1.ttl',
        "LOC2" =>  __DIR__.'/files/GeoResourceTest/loc2.ttl',
        "LOC3" =>  __DIR__.'/files/GeoResourceTest/loc3.ttl',
    ];

    public function setUp() {

        parent::setup();
        $this->graphs = [];
        $this->graphUrl = sprintf("%1\$scrdo-CFPP2000_35_SOUND", config('corpusparole.corpus_doc_id_base_uri'));
        foreach(self::TEST_DOCS as $k => $ttl) {

            $this->graphs[$k] = new EasyRdf\Graph($this->graphUrl, sprintf(file_get_contents($ttl), config('corpusparole.corpus_doc_id_base_uri'), config('corpusparole.corpus_id_scheme')));
        }
    }

    public function getGeoResource($key) {

        $graph = $this->graphs[$key];
        $providedCHO = $graph->get("<".config('corpusparole.corpus_doc_id_base_uri')."crdo-CFPP2000_35_SOUND>", "<http://www.europeana.eu/schemas/edm/aggregatedCHO>");
        $places = $graph->allOfType("<http://www.europeana.eu/schemas/edm/Place>");
        assert(count($places)>0);
        $place = $places[0];

        return new GeoResource($place->getUri(), $graph, $providedCHO);

    }

    public function getGeoResourceEdit($key) {
        $graph = $this->graphs[$key];
        $doc = new Document($this->graphUrl, $graph);

        return $doc->addGeoInfo();

    }

    public function testConstructor() {

        $this->assertNotNull($this->graphs, 'Graphs shoud not be null');

        $geoResource = $this->getGeoResource("LOC1");

        $this->assertNotNull($geoResource);
    }

    public function testGetRefLoc() {
        $geoResource = $this->getGeoResource("LOC1");

        $refLoc = $geoResource->getRefLocs();

        $this->assertEquals(['http://sws.geonames.org/6618626/'], $refLoc);

    }

    public function testGetRefLocNull() {
        $geoResource = $this->getGeoResource("LOC2");

        $refLoc = $geoResource->getRefLocs();

        $this->assertEmpty($refLoc);

    }

    public function testGetRefLocMultiple() {
        $geoResource = $this->getGeoResource("LOC3");

        $refLocs = $geoResource->getRefLocs();

        $this->assertTrue(is_array($refLocs));
        $this->assertCount(2,$refLocs);
        $this->assertEquals(['http://sws.geonames.org/6618626/', 'http://fr.dbpedia.org/resource/Gramazie'], $refLocs);


    }

    public function testNotes() {
        $geoResource = $this->getGeoResource("LOC1");

        $notes = $geoResource->getNotes();

        $this->assertTrue(is_array($notes));
        $this->assertCount(4, $notes);

        $this->assertContainsOnlyInstancesOf("EasyRdf\Literal", $notes);

    }

    public function testLatitude() {

        $geoInfo = $this->getGeoResource("LOC1");

        $this->assertEquals(48.73194, $geoInfo->getLatitude()->getValue(),'Must have correct latitude');
        $this->assertInstanceOf(EasyRdf\Literal::class, $geoInfo->getLatitude(), "Latitude must be a literal");
        $this->assertEquals('http://www.w3.org/2001/XMLSchema#float', $geoInfo->getLatitude()->getDatatypeUri(), "Datatype title must be 'http://www.w3.org/2001/XMLSchema#float'");
    }

    public function testLongitude() {

        $geoInfo = $this->getGeoResource("LOC1");

        $this->assertEquals(7.70833, $geoInfo->getLongitude()->getValue(),'Must have correct longitude');
        $this->assertInstanceOf(EasyRdf\Literal::class, $geoInfo->getLongitude(), "Longitude must be a literal");
        $this->assertEquals('http://www.w3.org/2001/XMLSchema#float', $geoInfo->getLongitude()->getDatatypeUri(), "Datatype title must be 'http://www.w3.org/2001/XMLSchema#float'");
    }



    public function testJsonSerialize() {
        $geoResource = $this->getGeoResource("LOC1");

        $json = $geoResource->jsonSerialize();

        $this->assertEquals(["ref-locs", "notes", "latitude", "longitude"], array_keys($json));
        $this->assertEquals(["http://sws.geonames.org/6618626/"], $json['ref-locs']);

        $notes = $json['notes'];
        $this->assertTrue(is_array($notes));
        $this->assertCount(4, $notes);

    }


    public function testJsonSerializeNull() {
        $geoResource = $this->getGeoResource("LOC2");

        $json = $geoResource->jsonSerialize();

        $this->assertEmpty($json['ref-locs']);

    }

    public function testJsonSerializeMultipleRefLocs() {
        $geoResource = $this->getGeoResource("LOC3");

        $json = $geoResource->jsonSerialize();

        $this->assertEquals(["ref-locs", "notes", "latitude", "longitude"], array_keys($json));
        $this->assertEquals(["http://sws.geonames.org/6618626/", "http://fr.dbpedia.org/resource/Gramazie"], $json['ref-locs']);

    }

    public function testSetRefLocs() {

        $geoResource = $this->getGeoResourceEdit("LOC1");



        $oldRefLocs = $geoResource->getRefLocs();
        sort($oldRefLocs);

        $newRefLocs = [ 'http://sws.geonames.org/2643743/' ];

        $geoResource->setRefLocs($newRefLocs);

        $refLoc = $geoResource->getRefLocs();

        $this->assertEquals(['http://sws.geonames.org/2643743/'], $refLoc);

        $geoResource->commit();

        $deltaList = $geoResource->getDeltaList();

        $this->assertNotNull($deltaList);
        $this->assertCount(1, $deltaList, "Must have one delta");


        $delta = $deltaList[0];

        $this->assertTrue($delta->getDeletedGraph()->isEmpty(), "deleted graph must be empty");
        $this->assertCount(1, $delta->getDeleteWhere(), "Delete where must have one element");
        $this->assertNotNull($delta->getAddedGraph(), "Added graph is not null");
        $this->assertEquals(9, $delta->getAddedGraph()->countTriples(), "Added graph must have 7 triples");
        $places = $delta->getAddedGraph()->allOfType("http://www.europeana.eu/schemas/edm/Place");
        $this->assertCount(1, $places);
        $place = $places[0];
        $sames = $places[0]->all('<http://www.w3.org/2002/07/owl#sameAs>');
        $this->assertCount(1, $sames);
        $this->assertEquals('http://sws.geonames.org/2643743/', $sames[0]->getUri());

    }


}
