<?php

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

class PerformanceTest extends BaseTest
{

    public function testCreateLargeDatasetWithSmartDataSources()
    {
        $totalContexts = 1000000; // 1 million context
        $smartDataUnits = $this->createSampleSmartDataUnits(30); // 30 sample smart data units
        $smartDataSourcesSignatures = $this->createSampleSmartDataSignatures(300); // 300 sample smart data units
        $smartDataSourcesSpheres = $this->createSampleSmartDataSpheres(300); // 300 sample smart data units
        $smartDataSourcesTimestamps = $this->createSampleSmartDataTimestamps(100); // 300 sample smart data units

        $lastTime = time();
        $pendingContexts = $totalContexts;
        while ($pendingContexts > 0) {
            $sources = array_merge($this->randomSelect($smartDataSourcesSignatures, 3), $this->randomSelect($smartDataSourcesSpheres, 2));
            $timestamp = $this->randomSelect($smartDataSourcesTimestamps, 1)[0];
            $units = $this->randomSelect($smartDataUnits, 1);

            $body = array("content" => ["meta" => true], "t0"=> $timestamp[0], "t1" => $timestamp[1], "features" => ["tags" => "sim"], "smartDataUnits" => $units, "smartDataSources" => $sources);        
            $response = $this->app->handle($this->_createRequest('POST', '/create/performance', $body));
            $this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
            if ($pendingContexts % 10000 == 0 && $pendingContexts != $totalContexts) {                
                $inserts = 10000 / (time() - $lastTime);
                $lastTime = time();
                fwrite(STDERR, "Remaining $pendingContexts - $inserts inserts/s. \n");
            }
            $pendingContexts--;
        }        
    }

    private function randomSelect($items, $count) {
        $keys = array_rand($items, $count);

        if ($count == 1) {
            return [$items[$keys]];
        } else {
            $random_values = array_map(function($key) use ($items) {
                return $items[$key];
            }, $keys);
            
            return $random_values;
        }
    }

    private function createSampleSmartDataUnits($count) {
        $result = [];
        while ($count-- >= 0) {
            $result[] = rand();
        }
        return $result;
    }

    private function createSampleSmartDataSignatures($count) {
        $result = [];
        while ($count-- >= 0) {
            $result[] = bin2hex(random_bytes(18));
        }
        return $result;
    }

    private function createSampleSmartDataSpheres($count) {
        $result = [];
        while ($count-- >= 0) {
            $result[] = [rand(), rand(), rand(), rand(1,10)];
        }
        return $result;
    }

    private function createSampleSmartDataTimestamps($count) {
        $result = [];
        while ($count-- >= 0) {
            if ($count % 7 == 0) {
                $result[] = [-1, rand()];
            } else if ($count % 5 == 0) {
                $result[] = [rand(), -1];
            } else if ($count % 3 == 0) {
                $result[] = [-1, -1];
            } else {
                $timestamp = [rand(), rand()];
                if ($timestamp[1] < $timestamp[0]) {
                    $timestamp = array_reverse($timestamp);
                }
                $result[] = $timestamp;
            }
        }
        return $result;
    }
}