<?php

require_once 'api/setup.php';
require_once 'api/routes.php';
require 'BaseTest.php';

class CrudTest extends BaseTest
{

    public function testCreateInvalid()
    {
        $response = $this->app->handle($this->_createRequest('POST', '/create/test'));
        $this->assertEquals(400, $response->getStatusCode());
    }

    public function testCreateInvalidMissingContent()
    {
        $response = $this->app->handle($this->_createRequest('POST', '/create/test'));
        $this->assertEquals(400, $response->getStatusCode());
        $this->assertContains("missing body", json_decode($response->getBody(), true)['errors']);
    }

    public function testCreateInvalidMissingTags()
    {
        $body = array("content" => ["meta" => true, "features" => []]);        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));

        $this->assertEquals(400, $response->getStatusCode());
        $this->assertNotContains("content property empty", json_decode($response->getBody(), true)['errors']);
        $this->assertContains("features missing tags entry", json_decode($response->getBody(), true)['errors']);
    }

    public function testCreateInvalidInvalidT0T1()
    {
        $body = array("content" => ["meta" => true], "t0" => 'a');        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));

        $this->assertEquals(400, $response->getStatusCode());
        $this->assertContains("t0 and t1 must time integer timestamps", json_decode($response->getBody(), true)['errors']);

        $body = array("content" => ["meta" => true], "t1" => 'a');        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));

        $this->assertEquals(400, $response->getStatusCode());
        $this->assertContains("t0 and t1 must time integer timestamps", json_decode($response->getBody(), true)['errors']);

    }

    public function testCreate()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"]);        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
    }

    public function testCreateWithSmartDataUnit()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataUnits" => [10, 12]);        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
    }

    public function testCreateWithInvalidSmartDataUnit()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataUnits" => ["aaa", "eee"]);        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(400, $response->getStatusCode());
        $this->assertContains("smartDataUnits should be a array of longs", json_decode($response->getBody(), true)['errors']);
    }

    public function testCreateWithSmartDataSources()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
    }

    public function testCreateWithSmartDataSourcesInvalidSignature()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffds-af-2342", [1,2,3,5]]);        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(400, $response->getStatusCode());
        $this->assertContains("ffds-af-2342 is an invalid signature", json_decode($response->getBody(), true)['errors']);
    }

    public function testCreateWithSmartDataSourcesInvalidSphere()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdsaf2342", [1,2,3]]);        
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(400, $response->getStatusCode());
        $this->assertContains("[1,2,3] is an invalid sphere", json_decode($response->getBody(), true)['errors']);
    }

    public function testCreateGetWithSmartDataUnit()
    {

        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataUnits" => [10, 12]);
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));

        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertTrue(array_key_exists('result', $body), 'missing result');
        $this->assertTrue(array_key_exists('smartdataid', $body['result']), 'missing smartdataid');
        $id = $body['result']['smartdataid'];
        $response = $this->app->handle($this->_createRequest('GET', "/get/test/$id"));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertTrue(array_key_exists('result', $body), 'missing result');
        $this->assertTrue(array_key_exists('content', $body['result']), 'missing content');
        $this->assertEquals($body['result']['id'], $id, 'wrong smartdataid');
    }

    public function testAssociateWithSmartDataSources()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertTrue(array_key_exists('result', $body), 'missing result');
        $this->assertTrue(array_key_exists('smartdataid', $body['result']), 'missing smartdataid');
        $id = $body['result']['smartdataid'];

        $body = ["smartdataids" => [$id], "smartDataSources" => ["ae7666", [4,5,6,7], [1,2,3,5]], "smartDataUnits" => [111,222]];
        $response = $this->app->handle($this->_createRequest('POST', '/associate/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertEquals(4, count($body['result'][0]['result']['smartDataSources']), "Wrong number of smartDataSources associated");
        $this->assertEquals(2, count($body['result'][0]['result']['smartDataUnits']), "Wrong number of smartDataUnits associated");
    }


    public function testUnassociateWithSmartDataSources()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertTrue(array_key_exists('result', $body), 'missing result');
        $this->assertTrue(array_key_exists('smartdataid', $body['result']), 'missing smartdataid');
        $id = $body['result']['smartdataid'];

        $body = ["smartdataids" => [$id], "smartDataSources" => ["ae7666", [4,5,6,7], [1,2,3,5]], "smartDataUnits" => [111,222]];
        $response = $this->app->handle($this->_createRequest('POST', '/associate/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertEquals(4, count($body['result'][0]['result']['smartDataSources']), "Wrong number of smartDataSources associated");
        $this->assertEquals(2, count($body['result'][0]['result']['smartDataUnits']), "Wrong number of smartDataUnits associated");

        $body = ["smartdataids" => [$id], "smartDataSources" => ["ae7666", [4,5,6,7]], "smartDataUnits" => [222]];
        $response = $this->app->handle($this->_createRequest('POST', '/unassociate/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertEquals(2, count($body['result'][0]['result']['smartDataSources']), "Wrong number of smartDataSources associated");
        $this->assertEquals(1, count($body['result'][0]['result']['smartDataUnits']), "Wrong number of smartDataUnits associated");
    }

    public function testQuery()
    {
        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
        $response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertTrue(array_key_exists('result', $body), 'missing result');
        $this->assertTrue(array_key_exists('smartdataid', $body['result']), 'missing smartdataid');
        $id = $body['result']['smartdataid'];

        $body = ["smartdataids" => [$id], "smartDataSources" => ["ae7666", [4,5,6,7], [1,2,3,5]], "smartDataUnits" => [111,222]];
        $response = $this->app->handle($this->_createRequest('POST', '/associate/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertEquals(4, count($body['result'][0]['result']['smartDataSources']), "Wrong number of smartDataSources associated");
        $this->assertEquals(2, count($body['result'][0]['result']['smartDataUnits']), "Wrong number of smartDataUnits associated");

        $body = ["smartDataSources" => [4,5,6,7]];
        $response = $this->app->handle($this->_createRequest('POST', '/query/test', $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertGreaterThan(0, count($body['result']), "Wrong number of results");
    }

    public function testContexts()
    {
        $domain = "performance";

        $body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
        $response = $this->app->handle($this->_createRequest('POST', "/create/$domain", $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertTrue(array_key_exists('result', $body), 'missing result');
        $this->assertTrue(array_key_exists('smartdataid', $body['result']), 'missing smartdataid');
        $id = $body['result']['smartdataid'];

        $body = ["smartdataids" => [$id], "smartDataSources" => ["ae7666", [4,5,6,7], [1,2,3,5]], "smartDataUnits" => [111,222]];
        $response = $this->app->handle($this->_createRequest('POST', "/associate/$domain", $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertEquals(4, count($body['result'][0]['result']['smartDataSources']), "Wrong number of smartDataSources associated");
        $this->assertEquals(2, count($body['result'][0]['result']['smartDataUnits']), "Wrong number of smartDataUnits associated");

        $start = time();
        $body = ["smartDataSources" => [[4,5,6,7]], "t0" => 10, "t1" => 300];
        $response = $this->app->handle($this->_createRequest('POST', "/contexts/$domain", $body));
        $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
        $response->getBody()->rewind();
        $body = json_decode($response->getBody()->getContents(), true);
        $this->assertGreaterThan(0, count($body['result']), "Wrong number of results");
    }
}