<?php
/**
 * This file is part of the Cloudinary PHP package.
 *
 * (c) Cloudinary
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Cloudinary\Test\Unit\Transformation\Common;

use Cloudinary\Test\TransformationTestCase;
use Cloudinary\Transformation\Effect;
use Cloudinary\Transformation\Expression\UVal;
use Cloudinary\Transformation\Expression\UVar;
use Cloudinary\Transformation\Qualifier;
use Cloudinary\Transformation\Resize;

/**
 * Class TransformationVariableTest
 */
final class TransformationVariableTest extends TransformationTestCase
{
    protected static $stringVariable;
    protected static $stringVariableStr;

    protected static $integerVariable1;
    protected static $integerVariable1Str;

    protected static $integerVariable2;
    protected static $integerVariable2Str;

    protected static $integerExpression1;
    protected static $integerExpression1Raw;
    protected static $integerExpression1Str;

    protected static $integerExpression2;
    protected static $integerExpression2Raw;
    protected static $integerExpression2Str;

    protected static $floatExpression1;
    protected static $floatExpression1Str;

    public static function setUpBeforeClass(): void
    {
        parent::setUpBeforeClass(); // TODO: Change the autogenerated stub

        self::$stringVariable    = UVar::uVar('svar');
        self::$stringVariableStr = ('$svar');

        self::$integerVariable1    = UVar::uVar('ivar1');
        self::$integerVariable1Str = '$ivar1';

        self::$integerVariable2    = UVar::uVar('$ivar2');
        self::$integerVariable2Str = '$ivar2';

        self::$integerExpression1    = UVal::int(100)->add()->int(1);
        self::$integerExpression1Raw = '100 + 1';
        self::$integerExpression1Str = '100_add_1';

        self::$integerExpression2    = UVal::int(200)->subtract()->int(2);
        self::$integerExpression2Raw = '200 - 2';
        self::$integerExpression2Str = '200_sub_2';

        self::$floatExpression1 = UVal::float(1)->divide()->float(3.14159265359);
        self::$floatExpression1Str = '1_div_3.14159265359';
    }

    public function testTransformationVariables()
    {
        $expected = 'c_thumb,g_' . self::$stringVariableStr . ',h_' . self::$integerExpression2Str .
                    ',w_' . self::$integerExpression1Str . ',x_' . self::$integerVariable1Str . ',y_' .
                    self::$integerVariable2Str;

        $th = Resize::thumbnail(
            self::$integerExpression1,
            self::$integerExpression2,
            self::$stringVariable,
            self::$integerVariable1,
            self::$integerVariable2
        );

        self::assertComponentEquals($expected, $th);

        $th = Resize::thumbnail()
                    ->width(self::$integerExpression1)
                    ->height(self::$integerExpression2)
                    ->gravity(self::$stringVariable)
                    ->x(self::$integerVariable1)
                    ->y(self::$integerVariable2);

        self::assertComponentEquals($expected, $th);

        $th->width(self::$integerExpression1Raw)->height(self::$integerExpression2Raw);

        self::assertComponentEquals($expected, $th);

        $e = Effect::generic(self::$stringVariable, self::$integerExpression1);

        self::assertComponentEquals('e_' . self::$stringVariableStr .':' . self::$integerExpression1Str, $e);

        $e = Effect::generic(self::$stringVariableStr, self::$integerExpression1Str);

        self::assertComponentEquals('e_' . self::$stringVariableStr .':' . self::$integerExpression1Str, $e);

        $nt = Qualifier::namedTransformation(self::$stringVariable);

        self::assertComponentEquals('t_' . self::$stringVariableStr, $nt);

        $q = Qualifier::quality(self::$floatExpression1);

        self::assertComponentEquals('q_' . self::$floatExpression1Str, $q);
    }

    /**
     * @param        $expectedStr
     * @param        $component
     * @param string $messages
     */
    private function assertComponentEquals($expectedStr, $component, string $messages = ''): void
    {
        self::assertEquals($expectedStr, (string)$component, $messages);
    }
}
