<?php

use PHPUnit\Framework\TestCase;

class DeviceTest extends TestCase {

    const COOKIE_FILE='./cookie_file';
    const USERNAME='DeviceTest';

    protected function setUp():void {
        database::connect();
        try {
            Log::init(Log::LOGLEVEL_DEBUG);
            session::init(new DummySession());
            $user=user::getByName(DeviceTest::USERNAME);
            if(!$user){
                database::begin();
                session::becomeAdmin();
                $user=user::getFirstAdmin();
                session::set('user', $user);
                session::set('userId', $user['id']);
                $user=user::create(array(
                    'name'=>DeviceTest::USERNAME,
                    'fullname'=>DeviceTest::USERNAME,
                    'email'=>DeviceTest::USERNAME.'@bogus.bogus',
                    'password'=>'UselessPassword',
                    'isactive'=>0
                ))['created'];
                session::revokeAdmin();
                database::commit();
                session::destroy();
                session::init(new DummySession());
            }
            session::set('user', $user);
            session::set('userId', $user['id']);
            session::refreshProjectPermissions();
        } catch (BadRequestException $e) {
            echo $e->getMessage();
            $this->fail('BadRequestException on session::init');
        } catch (NotFoundException $e) {
            echo $e->getMessage();
            $this->fail('NotFoundException on session::init');
        } catch (ServerException $e) {
            echo $e->getMessage();
            $this->fail('ServerException on session::init');
        }
        database::begin();
    }

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

	/**
	 * @param string $url
	 * @param string $json
	 * @param string $key
	 * @param string $sid
	 * @return bool|mixed|string
	 * @throws Exception
	 */
    public function post(string $url, string $json, string $key='', string $sid=''): mixed {
        return self::httpRequest('POST', $url, $json, $key, $sid);
    }

	/**
	 * @param string $url
	 * @param string $json
	 * @param string $key
	 * @param string $sid
	 * @return bool|mixed|string
	 * @throws Exception
	 */
    public function get(string $url, string $json, string $key='', string $sid=''): mixed {
        return self::httpRequest('GET', $url, $json, $key, $sid);
    }

	/**
	 * @param string $method
	 * @param string $url
	 * @param array $request
	 * @param string $key
	 * @param string $sid
	 * @return bool|mixed|string
	 * @throws Exception
	 */
    private function httpRequest(string $method, string $url, array|string $request, string $key='', string $sid=''): mixed {
        $method=strtoupper($method);
        $ch = curl_init($url);
        $options = array(
            CURLOPT_COOKIEFILE => '',
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_HEADER          => false,
            CURLOPT_CONNECTTIMEOUT  => 20,
            CURLOPT_TIMEOUT         => 20,
            CURLOPT_SSL_VERIFYHOST  => 0,
            CURLOPT_SSL_VERIFYPEER  => false,
            CURLOPT_UNRESTRICTED_AUTH => true
        );
        if(''!==$key){
            $options[CURLOPT_HTTPHEADER]=array("X-IceBear-API-Key: ".$key);
            //Device API should also accept API key in an Authorization: Bearer header
            //$options[CURLOPT_HTTPHEADER]=array("Authorization: Bearer ".$key);
        }
        if(''!==$sid){
            curl_setopt($ch, CURLOPT_COOKIEFILE, self::COOKIE_FILE);
            curl_setopt($ch, CURLOPT_COOKIEJAR, self::COOKIE_FILE);
            curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID='.$sid);
        }
        if('POST'==$method){
            $options[CURLOPT_POST]=1;
            if(isset($request['rawPostBody'])){
                $options[CURLOPT_POSTFIELDS]=$request['rawPostBody'];
                if(false!==json_decode($request['rawPostBody'])){
                    $requestHeaders[]='Content-Type: application/json';
                    $options[CURLOPT_HTTPHEADER]=$requestHeaders;
                }
            } else {
                $options[CURLOPT_POSTFIELDS]=$request;
            }
        } else if('GET'!==$method){
            throw new Exception('Only GET/POST supported');
        }
        curl_setopt_array($ch,$options);
        $data = curl_exec($ch);

        $redirectUrl=curl_getinfo($ch, CURLINFO_REDIRECT_URL);
        curl_close($ch);
        if(empty($redirectUrl)){
            return $data;
        } else {
            return $redirectUrl;
        }
    }

    /**
     * Stops test engine whining about no tests in this parent class
     */
    public function testDummy(){
        self::assertEquals(1,1);
    }

}
