<?php


namespace Gek\Captcha\Tests;


use Gek\Captcha\CaptchaBuilder;
use Gek\Captcha\RgbColor;
use PHPUnit\Framework\TestCase;

class CaptchaBuilderTest extends TestCase
{
    protected $filePath;

    public function __construct(?string $name = null, array $data = [], $dataName = '')
    {
        parent::__construct($name, $data, $dataName);
        $this->filePath = __DIR__ . DIRECTORY_SEPARATOR .'test_file.jpg';
        if(file_exists($this->filePath)){
            unlink($this->filePath);
        }
    }

    public function testSetters(){

        $reflect = new \ReflectionClass(CaptchaBuilder::class);

        $bld = new CaptchaBuilder();

        $bld->setPhrase('asdf');
        $prp = $reflect->getProperty('phrase');
        $prp->setAccessible(true);

        $this->assertEquals(
            'asdf',
            $prp->getValue($bld)
        );

        $clr = RgbColor::create();
        $bld->setTextColor($clr);
        $prp = $reflect->getProperty('textColor');
        $prp->setAccessible(true);

        $this->assertTrue(
            $clr === $prp->getValue($bld)
        );

        $clr = RgbColor::create();
        $bld->setFrontLineColor($clr);
        $prp = $reflect->getProperty('frontLineColor');
        $prp->setAccessible(true);

        $this->assertTrue(
            $clr === $prp->getValue($bld)
        );

        $clr = RgbColor::create();
        $bld->setBackLineColor($clr);
        $prp = $reflect->getProperty('backLineColor');
        $prp->setAccessible(true);

        $this->assertTrue(
            $clr === $prp->getValue($bld)
        );

        $clr = RgbColor::create();
        $bld->setBackgroundColor($clr);
        $prp = $reflect->getProperty('backgroundColor');
        $prp->setAccessible(true);

        $this->assertTrue(
            $clr === $prp->getValue($bld)
        );


        $bld->setMinBackLineCount(155);
        $prp = $reflect->getProperty('minBackLineCount');
        $prp->setAccessible(true);

        $this->assertEquals(
            155,
            $prp->getValue($bld)
        );

        $bld->setMaxBackLineCount(122);
        $prp = $reflect->getProperty('maxBackLineCount');
        $prp->setAccessible(true);

        $this->assertEquals(
            122,
            $prp->getValue($bld)
        );

        $bld->setMinFrontLineCount(645);
        $prp = $reflect->getProperty('minFrontLineCount');
        $prp->setAccessible(true);

        $this->assertEquals(
            645,
            $prp->getValue($bld)
        );

        $bld->setMaxFrontLineCount(452);
        $prp = $reflect->getProperty('maxFrontLineCount');
        $prp->setAccessible(true);

        $this->assertEquals(
            452,
            $prp->getValue($bld)
        );

        $bld->setMaxCharAngle(555);
        $prp = $reflect->getProperty('maxCharAngle');
        $prp->setAccessible(true);

        $this->assertEquals(
            555,
            $prp->getValue($bld)
        );

        $bld->setMaxCharOffset(777);
        $prp = $reflect->getProperty('maxCharOffset');
        $prp->setAccessible(true);

        $this->assertEquals(
            777,
            $prp->getValue($bld)
        );

        $bld->setInterpolation(false);
        $prp = $reflect->getProperty('interpolation');
        $prp->setAccessible(true);

        $this->assertFalse(
            $prp->getValue($bld)
        );
        $bld->setInterpolation(true);
        $this->assertTrue(
            $prp->getValue($bld)
        );

        $bld->setFontPath("asdf");
        $prp = $reflect->getProperty('fontPath');
        $prp->setAccessible(true);

        $this->assertEquals(
            "asdf",
            $prp->getValue($bld)
        );
        $bld->setFontPath(null);
        $this->assertNull(
            $prp->getValue($bld)
        );

        $bld->setDistortion(false);
        $prp = $reflect->getProperty('distortion');
        $prp->setAccessible(true);

        $this->assertFalse(
            $prp->getValue($bld)
        );
        $bld->setDistortion(true);
        $this->assertTrue(
            $prp->getValue($bld)
        );

        $bld->setUseEffects(false);
        $prp = $reflect->getProperty('useEffects');
        $prp->setAccessible(true);

        $this->assertFalse(
            $prp->getValue($bld)
        );
        $bld->setUseEffects(true);
        $this->assertTrue(
            $prp->getValue($bld)
        );

        $bld->setImageQuality(456);
        $prp = $reflect->getProperty('imageQuality');
        $prp->setAccessible(true);

        $this->assertEquals(
            456,
            $prp->getValue($bld)
        );

    }

    public function testGetters(){
        $bld = new CaptchaBuilder();

        $bld->setPhrase('qwerty');
        $this->assertEquals(
            'qwerty',
            $bld->getPhrase()
        );

        $bld->setPhrase('qwerty');
        $this->assertEquals(
            'qwerty',
            $bld->getPhrase()
        );

        $clr = RgbColor::create();
        $bld->setTextColor($clr);
        $this->assertTrue(
            $clr === $bld->getTextColor()
        );

        $clr = RgbColor::create();
        $bld->setFrontLineColor($clr);
        $this->assertTrue(
            $clr === $bld->getFrontLineColor()
        );

        $clr = RgbColor::create();
        $bld->setBackLineColor($clr);
        $this->assertTrue(
            $clr === $bld->getBackLineColor()
        );

        $clr = RgbColor::create();
        $bld->setBackgroundColor($clr);
        $this->assertTrue(
            $clr === $bld->getBackgroundColor()
        );

        $bld->setMinBackLineCount(1234);
        $this->assertEquals(
            1234,
            $bld->getMinBackLineCount()
        );

        $bld->setMaxBackLineCount(7854);
        $this->assertEquals(
            7854,
            $bld->getMaxBackLineCount()
        );

        $bld->setMinFrontLineCount(354);
        $this->assertEquals(
            354,
            $bld->getMinFrontLineCount()
        );

        $bld->setMaxFrontLineCount(4445);
        $this->assertEquals(
            4445,
            $bld->getMaxFrontLineCount()
        );

        $this->assertNull($bld->getImage());

        $bld->setMaxCharAngle(58);
        $this->assertEquals(
            58,
            $bld->getMaxCharAngle()
        );

        $bld->setMaxCharOffset(44);
        $this->assertEquals(
            44,
            $bld->getMaxCharOffset()
        );

        $bld->setInterpolation(false);
        $this->assertFalse(
            $bld->isInterpolation()
        );
        $bld->setInterpolation(true);
        $this->assertTrue(
            $bld->isInterpolation()
        );

        $bld->setDistortion(false);
        $this->assertFalse(
            $bld->isDistortion()
        );
        $bld->setDistortion(true);
        $this->assertTrue(
            $bld->isDistortion()
        );

        $bld->setUseEffects(false);
        $this->assertFalse(
            $bld->isUseEffects()
        );
        $bld->setUseEffects(true);
        $this->assertTrue(
            $bld->isUseEffects()
        );

        $bld->setImageQuality(4565);
        $this->assertEquals(
            4565,
            $bld->getImageQuality()
        );

        $bld = new CaptchaBuilder();

        $bld->build();
        $this->assertIsResource(
            $bld->getImage()
        );

    }

    public function testConstructs(){
        $bld = new CaptchaBuilder("aaa");
        $this->assertEquals(
            "aaa",
            $bld->getPhrase()
        );
    }

    public function testBuild(){
        $bld = new CaptchaBuilder();
        $this->assertNull($bld->getImage());
        $res = $bld->build();
        $this->assertTrue($bld === $res);
        $this->assertIsResource($bld->getImage());
    }

    public function testSave(){
        $bld = new CaptchaBuilder();
        $bld->build()
            ->save($this->filePath);
        $this->assertFileExists($this->filePath);
        $this->assertIsResource($bld->getImage());

        if(file_exists($this->filePath)){
            unlink($this->filePath);
        }


        $bld = new CaptchaBuilder();
        $bld->build()
            ->save($this->filePath,true);
        $this->assertFileExists($this->filePath);
        $this->assertNull($bld->getImage());

    }





    public function testGetImageData(){
        $bld = new CaptchaBuilder();
        $imgData = $bld->build()->getImageData();
        $this->assertNotEmpty($imgData);
        $this->assertTrue('string' === gettype($imgData));
        $this->assertIsResource($bld->getImage());

        $bld = new CaptchaBuilder();
        $imgData = $bld->build()->getImageData(true);
        $this->assertNotEmpty($imgData);
        $this->assertTrue('string' === gettype($imgData));
        $this->assertNull($bld->getImage());
    }

    public function testGetBase64String(){
        $bld = new CaptchaBuilder();
        $imgData = $bld->build()->getImageData();
        $bs64 = $bld->getBase64String();
        $this->assertNotEmpty($imgData);
        $this->assertTrue('string' === gettype($imgData));
        $this->assertTrue(base64_encode($imgData) === $bs64);
        $this->assertIsResource($bld->getImage());

        $bld = new CaptchaBuilder();
        $imgData = $bld->build()->getImageData();
        $bs64 = $bld->getBase64String(true);
        $this->assertNotEmpty($imgData);
        $this->assertTrue('string' === gettype($imgData));
        $this->assertTrue(base64_encode($imgData) === $bs64);
        $this->assertNull($bld->getImage());

    }

    public function testGetInlineBase64(){
        $bld = new CaptchaBuilder();
        $bs64 = $bld->build()->getBase64String();
        $inline = $bld->getInlineBase64();
        $this->assertNotEmpty($inline);
        $this->assertTrue('string' === gettype($inline));
        $this->assertTrue((false !== strpos($inline,$bs64)));
        $this->assertTrue(('data:image/jpeg;base64,' == substr($inline,0,23)));
        $this->assertIsResource($bld->getImage());

        $bld = new CaptchaBuilder();
        $bs64 = $bld->build()->getBase64String();
        $inline = $bld->getInlineBase64(true);
        $this->assertNotEmpty($inline);
        $this->assertTrue('string' === gettype($inline));
        $this->assertTrue((false !== strpos($inline,$bs64)));
        $this->assertTrue(('data:image/jpeg;base64,' == substr($inline,0,23)));
        $this->assertNull($bld->getImage());
    }


    public function testCreate(){
        $bld =  CaptchaBuilder::create("aaa");
        $this->assertEquals(
            "aaa",
            $bld->getPhrase()
        );

        $bld =  CaptchaBuilder::create();
        $this->assertNotEmpty(
            $bld->getPhrase()
        );
        $this->assertIsString($bld->getPhrase());
    }



}