<?php

use PHPUnit\Framework\TestCase;

class SynchWebSynchrotronTest extends TestCase {

    public static $synchWebSynchrotrons;

    public static $authTokens=array();

    const HANDLER='SynchWeb';

    public function setUp():void {
        database::connect();
        session::init(new DummySession());
        session::becomeAdmin();
        $user=user::getFirstAdmin();
        session::set('user', $user);
        session::set('userId', $user['id']);
        session::revertAdmin();
    }

	public static function getSynchrotrons(){
		if(!isset(static::$synchWebSynchrotrons)){
			$config=@file_get_contents(__DIR__.'/../../../../testconfig.json');
			$config=json_decode($config,true);
			foreach ($config['synchrotrons'] as &$synchrotron){
				if($synchrotron['handler']===self::HANDLER){
					static::$synchWebSynchrotrons[]=array($synchrotron);
				}
			}
		}
		return static::$synchWebSynchrotrons;
	}

    /**
     * @dataProvider getSynchrotrons
     * @param $synchrotron
     */
    public function testHandlerIsCorrect($synchrotron){
        self::assertEquals(self::HANDLER,$synchrotron['handler'], $synchrotron['name'].' is not a '.self::HANDLER.' synchrotron');
    }

    /**
     * @dataProvider getSynchrotrons
     * @param $synchrotron
     */
    public function testAuthenticate($synchrotron){
        $result=corsproxy::doPost(
            $synchrotron['baseuri'].'authenticate',
            array(
                'rawPostBody'=>'{ "login":"'.$synchrotron['user'].'", "password":"'.$synchrotron['pass'].'" }'
            ));
        self::assertNotEmpty($result, $synchrotron['name'].' returned an empty result');
        $decoded=json_decode($result, true);
        self::assertNotEmpty($decoded, $synchrotron['name'].' returned a non-JSON response: '.$result);
        self::assertArrayHasKey('jwt', $decoded, $synchrotron['name'].' response does not have a JWT token');
        static::$authTokens[$synchrotron['name']]=$decoded['jwt'];
    }

    /**
     * @dataProvider getSynchrotrons
	 * @depends testAuthenticate
     * @param $synchrotron
     */
    public static function testGetProposals($synchrotron){
        self::assertArrayHasKey($synchrotron['name'], static::$authTokens, 'Auth token not saved for '.$synchrotron['name']);
        $token=static::$authTokens[$synchrotron['name']];
        $result=corsproxy::doGet(
            $synchrotron['baseuri'].'proposal?page=1&per_page=50&all=1&next=1',
            array('httpHeaders'=>['Authorization: Bearer '.$token])
		);
        self::assertNotEmpty($result, $synchrotron['name'].' returned an empty result');
        $result=json_decode($result, true);
        self::assertNotEmpty($result, $synchrotron['name'].' returned a non-JSON response');
        self::assertArrayNotHasKey('error', $result, $synchrotron['name'].' returned an error');
        self::assertArrayHasKey('total', $result, $synchrotron['name'].' returned no "total" key');
        self::assertArrayHasKey('data', $result, $synchrotron['name'].' returned no "data" key');
        foreach(['PROPOSAL','PROPOSALCODE','PROPOSALNUMBER'] as $key){
            self::assertArrayHasKey($key, $result['data'][0], $synchrotron['name'].' returned no "'.$key.'" key');
        }
        self::assertEquals($result['data'][0]['PROPOSAL'], $result['data'][0]['PROPOSALCODE'].$result['data'][0]['PROPOSALNUMBER']);
    }

    /**
     * @dataProvider getSynchrotrons
	 * @depends testAuthenticate
	 * @param $synchrotron
     */
    public static function testGetVisits($synchrotron){
        self::assertArrayHasKey($synchrotron['name'], static::$authTokens, 'Auth token not saved for '.$synchrotron['name']);
        $token=static::$authTokens[$synchrotron['name']];
        $result=corsproxy::doGet(
            $synchrotron['baseuri'].'proposal/visits?page=1&per_page=1000&all=1&prop='.$synchrotron['proposal'],
            array('httpHeaders'=>['Authorization: Bearer '.$token])
		);
        self::assertNotEmpty($result, $synchrotron['name'].' returned an empty result');
        $result=json_decode($result, true);
        self::assertNotEmpty($result, $synchrotron['name'].' returned a non-JSON response');
        self::assertArrayNotHasKey('error', $result, $synchrotron['name'].' returned an error');
        self::assertArrayHasKey('total', $result, $synchrotron['name'].' returned no "total" key');
        self::assertArrayHasKey('data', $result, $synchrotron['name'].' returned no "data" key');
        foreach(['VISIT','ST','EN','SESSIONID','BEAMLINENAME','PROPOSAL','PROPOSALID'] as $key){
            self::assertArrayHasKey($key, $result['data'][0], $synchrotron['name'].' returned no "'.$key.'" key');
        }
    }

    /**
     * @dataProvider getSynchrotrons
	 * @depends testAuthenticate
	 * @param $synchrotron
     */
    public static function testGetLabContacts($synchrotron){
        self::assertArrayHasKey($synchrotron['name'], static::$authTokens, 'Auth token not saved for '.$synchrotron['name']);
        $token=static::$authTokens[$synchrotron['name']];
        $result=corsproxy::doGet(
            $synchrotron['baseuri'].'contact?page=1&per_page=1000&all=1&prop='.$synchrotron['proposal'],
            array('httpHeaders'=>['Authorization: Bearer '.$token])
		);
        self::assertNotEmpty($result, $synchrotron['name'].' returned an empty result');
        $result=json_decode($result, true);
        self::assertNotEmpty($result, $synchrotron['name'].' returned a non-JSON response');
        self::assertArrayNotHasKey('error', $result, $synchrotron['name'].' returned an error');
        self::assertArrayHasKey('total', $result, $synchrotron['name'].' returned no "total" key');
        self::assertArrayHasKey('data', $result, $synchrotron['name'].' returned no "data" key');
        foreach(['LABCONTACTID','CARDNAME','GIVENNAME','FAMILYNAME'] as $key){
            self::assertArrayHasKey($key, $result['data'][0], $synchrotron['name'].' returned no "'.$key.'" key');
        }
    }

    /**
     * @dataProvider getSynchrotrons
	 * @depends testAuthenticate
	 * @param $synchrotron
     */
    public static function testGetProteins($synchrotron){
        self::assertArrayHasKey($synchrotron['name'], static::$authTokens, 'Auth token not saved for '.$synchrotron['name']);
        $token=static::$authTokens[$synchrotron['name']];
        $result=corsproxy::doGet(
            $synchrotron['baseuri'].'sample/proteins?page=1&per_page=1000&all=1&prop='.$synchrotron['proposal'],
            array('httpHeaders'=>['Authorization: Bearer '.$token])
		);
        self::assertNotEmpty($result, $synchrotron['name'].' returned an empty result');
        $result=json_decode($result, true);
        self::assertNotEmpty($result, $synchrotron['name'].' returned a non-JSON response');
        self::assertArrayNotHasKey('error', $result, $synchrotron['name'].' returned an error');
        self::assertArrayHasKey('total', $result, $synchrotron['name'].' returned no "total" key');
        self::assertArrayHasKey('data', $result, $synchrotron['name'].' returned no "data" key');
        foreach(['NAME','ACRONYM','PROTEINID','PROP','SAFETYLEVEL'] as $key){
            self::assertArrayHasKey($key, $result['data'][0], $synchrotron['name'].' returned no "'.$key.'" key');
        }
    }


}