<?php

use PHPUnit\Framework\TestCase;

class ReferenceDataLoaderTest extends TestCase {

    protected function setUp(): void
    {
        database::connect();
        try {
            include_once(__DIR__.'/../../../../upgrade/includes/ReferenceDataLoader.class.php');
            Log::init(Log::LOGLEVEL_DEBUG);
            session::init(new DummySession());
            session::becomeAdmin();
            $user = user::getFirstAdmin();
            session::set('user', $user);
            session::set('userId', $user['id']);
            session::refreshProjectPermissions();
            echo "\n";
        } catch (BadRequestException) {
            $this->fail('BadRequestException on session::init');
        } catch (NotFoundException) {
            $this->fail('NotFoundException on session::init');
        } catch (ServerException) {
            $this->fail('ServerException on session::init');
        }
        database::begin();
    }

    protected function tearDown(): void
    {
        database::abort();
        session::destroy();
        Log::end();
    }

    private static $shipmentDestinations=array('synchrotrons'=>array(
        array(
            'name'=>'Test1',
            'shipmenthandler'=>'DefaultShipmentHandler',
            'apiBaseUri'=>'http://localhost',
            'clientBaseUri'=>'http://localhost'
        ),
        array(
            'name'=>'Test2',
            'shipmenthandler'=>'DefaultShipmentHandler',
            'apiBaseUri'=>'http://localhost',
            'clientBaseUri'=>'http://localhost',
            'geofence'=>[50,40,100]
        )
    ));

    private static $containerTypes=array('containertypes'=>array(
        array(
            'containercategory'=>'Test Category 1',
            'name'=>'Test Type 1',
            'positions'=>15
        )
    ));

    private static $projects=array('projects'=>array(
        array(
            'name'=>'Test Project 1',
            'description'=>'Project description'
        ),
        array(
            'name'=>'Test Project 2'
        )
    ));

    private static $usergroups=array('usergroups'=>array(
        array(
            'name'=>'Test Usergroup 1',
            'description'=>'Test usergroup description'
        )
    ));

    /**
     * @throws Exception
     */
    public function testLoadShipmentDestinations(){
        $testName="Test2";
        $existing=shipmentdestination::getByName($testName);
        self::assertEmpty($existing);
        ReferenceDataLoader::loadShipmentDestinations(static::$shipmentDestinations);
        $existing=shipmentdestination::getByName($testName);
        self::assertNotEmpty($existing);
        shipmentdestination::update($existing['id'], array('shipmenthandler'=>'DemoShipmentHandler'));
        $existing=shipmentdestination::getByName($testName);
        self::assertEquals('DemoShipmentHandler', $existing['shipmenthandler']);
        ReferenceDataLoader::loadShipmentDestinations(static::$shipmentDestinations);
        $existing=shipmentdestination::getByName($testName);
        self::assertNotEquals('DemoShipmentHandler', $existing['shipmenthandler']);
        self::assertTrue(1===preg_match('/^[0-9,-]*$/', $existing['geofence']));
    }

    /**
     * @throws Exception
     */
    public function testLoadContainerTypes(){
        $testTypeName="Test Type 1";
        $testCategoryName="Test Category 1";
        $existingType=containertype::getByName($testTypeName);
        $existingCategory=containercategory::getByName($testCategoryName);
        self::assertEmpty($existingType);
        self::assertEmpty($existingCategory);
        ReferenceDataLoader::loadContainerTypes(static::$containerTypes);
        $existingType=containertype::getByName($testTypeName);
        $existingCategory=containercategory::getByName($testCategoryName);
        self::assertNotEmpty($existingType);
        self::assertNotEmpty($existingCategory);
        containertype::update($existingType['id'], array('positions'=>20));
        $existingType=containertype::getByName($testTypeName);
        self::assertEquals(20, $existingType['positions']);
        ReferenceDataLoader::loadContainerTypes(static::$containerTypes);
        $existingType=containertype::getByName($testTypeName);
        self::assertEquals(15, $existingType['positions']);
    }

    /**
     * @throws NotFoundException
     * @throws BadRequestException
     * @throws ForbiddenException
     * @throws ServerException
     */
    public function testLoadProjects(){
        $existing=null;
        $testName='Test Project 1';
        try {
            $existing=project::getByName($testName);
        } catch (NotFoundException){
            //expected
        }
        self::assertEmpty($existing);
        ReferenceDataLoader::loadProjects(static::$projects);
        $existing=project::getByName($testName);
        self::assertNotEmpty($existing);
        $newDescription='New description';
        project::update($existing['id'],array('description'=>$newDescription));
        $existing=project::getByName($testName);
        self::assertEquals($newDescription, $existing['description'],'Project description update failed');
        ReferenceDataLoader::loadProjects(static::$projects);
        $existing=project::getByName($testName);
        self::assertEquals('Project description', $existing['description'], 'Reference data loader did not update project description');
    }

    /**
     * @throws NotFoundException
     * @throws BadRequestException
     * @throws ForbiddenException
     * @throws ServerException
     */
    public function testLoadUsergroups(){
        $existing=null;
        $testName='Test Usergroup 1';
        try {
            $existing=usergroup::getByName($testName);
        } catch (NotFoundException){
            //expected
        }
        self::assertEmpty($existing);
        ReferenceDataLoader::loadUsergroups(static::$usergroups);
        $existing=usergroup::getByName($testName);
        self::assertNotEmpty($existing);
        $newDescription='New description';
        usergroup::update($existing['id'],array('description'=>$newDescription));
        $existing=usergroup::getByName($testName);
        self::assertEquals($newDescription, $existing['description'],'Usergroup description update failed');
        ReferenceDataLoader::loadUsergroups(static::$usergroups);
        $existing=usergroup::getByName($testName);
        self::assertEquals('Test usergroup description', $existing['description'], 'Reference data loader did not update usergroup description');
    }


}