<?php


namespace calderawp\calderaforms\Tests\Integration\RestApi;



class CreateFileTest extends RestApiTestCase
{
    /**
     * @var string
     */
    protected $test_file;

    /** @inheritdoc */
    public function setUp()
    {
        $orig_file = __DIR__ . '/screenshot.jpeg';
        $this->test_file = '/tmp/screenshot.jpg';
        copy($orig_file, $this->test_file);
        parent::setUp(); // TODO: Change the autogenerated stub
    }

    /**
     * @covers \calderawp\calderaforms\cf2\RestApi\Endpoint::getArgs()
     * @covers \calderawp\calderaforms\cf2\RestApi\Endpoint::add_routes()
     * @covers \calderawp\calderaforms\cf2\RestApi\Register::initEndpoints()
     * @covers \calderawp\calderaforms\cf2\RestApi\Register::getNamespace()
     * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::getArgs()
     *
     * @since 1.8.0
     *
     * @group cf2
     * @group file
     * @group field
     * @group cf2_file
     */
    public function testRouteCanBeRequest()
    {
        $request = new \WP_REST_Request('GET', '/cf-api/v3');
        $response = rest_get_server()->dispatch($request);
        $this->assertTrue(
            array_key_exists(  '/cf-api/v3/file', $response->get_data()[ 'routes'] )
        );
        $this->assertTrue(
            in_array( 'POST', $response->get_data()[ 'routes'][ '/cf-api/v3/file' ]['methods'] )
        );

    }
    /**
     * Test we can upload files
     *
     * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
     *
     * @since 1.8.0
     *
     * @group cf2
     * @group file
     * @group field
     * @group cf2_file
     */
    public function testCreateItem()
    {

        wp_set_current_user(1 );
        $formId = 'cf2_file';
        $fieldId = 'cf2_file_1';
        $form = \Caldera_Forms_Forms::get_form( $formId );
        $control = \Caldera_Forms_Field_Util::generate_file_field_unique_id(
            \Caldera_Forms_Field_Util::get_field($fieldId,$form),
            $form
        );
        $nonce = \Caldera_Forms_Render_Nonce::create_verify_nonce($formId);

        $request = $this->createFileRequest($nonce, $formId, $control, $fieldId);

        $response = rest_get_server()->dispatch($request);


        $this->assertEquals(201, $response->get_status());
        $data = $response->get_data();
        $this->assertArrayHasKey( 'control', $data );
        $this->assertEquals($data[ 'control' ], $control );
    }

    /**
     * Test that file hashes must be valid to upload files
     *
     * @since 1.8.0
     *
     * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
     *

     * @group cf2
     * @group file
     * @group field
     * @group cf2_file
     */
    public function testInvalidHashes(){
        wp_set_current_user(1 );
        $formId = 'cf2_file';
        $fieldId = 'cf2_file_1';
        $form = \Caldera_Forms_Forms::get_form( $formId );
        $control = \Caldera_Forms_Field_Util::generate_file_field_unique_id(
            \Caldera_Forms_Field_Util::get_field($fieldId,$form),
            $form
        );
        $nonce = \Caldera_Forms_Render_Nonce::create_verify_nonce($formId);

        $request = $this->createFileRequest($nonce, $formId, $control, $fieldId);
        $request->set_param( 'hashes', [ 0 => '1111' ] );
        $response = rest_get_server()->dispatch($request);
        $this->assertEquals(412, $response->get_status());

    }

    /**
     * Test that file hashes must be valid to upload files
     *
     * @since 1.8.0
     *
     * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
     *
     * @group cf2
     * @group file
     * @group field
     * @group cf2_file
     */
    public function testCanNotUseWithoutValidFileField(){
        wp_set_current_user(1 );
        $formId = 'cf2_file';
        $fieldId = 'test_field_1'; //not a file field
        $form = \Caldera_Forms_Forms::get_form( $formId );
        $control = \Caldera_Forms_Field_Util::generate_file_field_unique_id(
            \Caldera_Forms_Field_Util::get_field($fieldId,$form),
            $form
        );
        $nonce = \Caldera_Forms_Render_Nonce::create_verify_nonce($formId);

        $request = $this->createFileRequest($nonce, $formId, $control, $fieldId);
        $response = rest_get_server()->dispatch($request);
        $this->assertEquals(403, $response->get_status());

    }

    /**
     * Test that an invalid nonce prevents creation
     *
     * @since 1.8.0
     *
     * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
     *
     * @group cf2
     * @group file
     * @group field
     * @group cf2_file
     */
    public function testInvalidNonce(){
        wp_set_current_user(1 );
        $formId = 'cf2_file';
        $fieldId = 'cf2_file_1';
        $form = \Caldera_Forms_Forms::get_form( $formId );
        $control = \Caldera_Forms_Field_Util::generate_file_field_unique_id(
            \Caldera_Forms_Field_Util::get_field($fieldId,$form),
            $form
        );
        $nonce = \Caldera_Forms_Render_Nonce::create_verify_nonce($formId . rand());

        $request = $this->createFileRequest($nonce, $formId, $control, $fieldId);
        $response = rest_get_server()->dispatch($request);
        $this->assertEquals(403, $response->get_status());

    }


    /**
     * Test that an invalid nonce prevents creation
     *
     * @since 1.8.0
     *
     * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
     * @covers \calderawp\calderaforms\cf2\Fields\Handlers\FileUpload::isAllowedType()
     * @covers \calderawp\calderaforms\cf2\Fields\Handlers\FileUpload::processFiles()
     *
     * @group cf2
     * @group file
     * @group field
     * @group cf2_file
     */
    public function testInvalidFileType(){
        wp_set_current_user(1 );
        $formId = 'cf2_file';
        $fieldId = 'cf2_file_3';
        $form = \Caldera_Forms_Forms::get_form( $formId );
        $control = \Caldera_Forms_Field_Util::generate_file_field_unique_id(
            \Caldera_Forms_Field_Util::get_field($fieldId,$form),
            $form
        );
        $nonce = \Caldera_Forms_Render_Nonce::create_verify_nonce($formId );

        $request = $this->createFileRequest($nonce,$formId,$control,$fieldId);

        $request->set_param('verify', $nonce);
        $request->set_param('formId', $formId);
        $request->set_param('control', $control);
        $request->set_param('fieldId', $fieldId);
        $request->set_param('hashes', [
            0 => md5_file($this->test_file)
        ]);

        $response = rest_get_server()->dispatch($request);
        $this->assertEquals(415, $response->get_status());

    }


    /**
     * Test that the transient with file data is set for next request.
     *
     * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
     *
     * @since 1.8.0
     *

     * @group cf2
     * @group file
     * @group field
     * @group cf2_file
     */
    public function testTransientSet(){
        wp_set_current_user(1 );
        $formId = 'cf2_file';
        $fieldId = 'cf2_file_1';
        $form = \Caldera_Forms_Forms::get_form( $formId );
        $control = \Caldera_Forms_Field_Util::generate_file_field_unique_id(
            \Caldera_Forms_Field_Util::get_field($fieldId,$form),
            $form
        );
        $nonce = \Caldera_Forms_Render_Nonce::create_verify_nonce($formId);

        $request = $this->createFileRequest($nonce, $formId, $control, $fieldId);
        $response = rest_get_server()->dispatch($request);

        $data = $response->get_data();
        $transdata = \Caldera_Forms_Transient::get_transient($data[ 'control' ]);
        $this->assertEquals( 1, count($transdata ) );

    }

	/**
	 * Test that the transient with file data is set for next request.
	 *
	 * @covers \calderawp\calderaforms\cf2\RestApi\File\CreateFile::createItem()
	 * @covers \calderawp\calderaforms\cf2\Fields\Handlers\Cf1FileUploader::scheduleFileDelete()
	 *
	 * @since 1.8.0
	 * @group cf2
	 * @group file
	 * @group field
	 * @group cf2_file
	 */
	public function testDeleteFile(){
		$data = new \stdClass();
		wp_set_current_user(1 );
		$formId = 'cf2_file';
		$fieldId = 'testScheduleDelete';
		$form = \Caldera_Forms_Forms::get_form( $formId );
		$control = \Caldera_Forms_Field_Util::generate_file_field_unique_id(
			\Caldera_Forms_Field_Util::get_field($fieldId,$form),
			$form
		);
		$nonce = \Caldera_Forms_Render_Nonce::create_verify_nonce($formId);
		add_filter( 'wp_handle_upload', function ($file) use ($data){
			$data->path = $file['file'];
			return $file;
		});
		$request = $this->createFileRequest($nonce, $formId, $control, $fieldId);
		rest_get_server()->dispatch($request);
		$this->assertTrue( file_exists($data->path ));

		/** @var \calderawp\calderaforms\cf2\Jobs\Scheduler $scheduler */
		$scheduler = caldera_forms_get_v2_container()->getService(\calderawp\calderaforms\cf2\Services\QueueSchedulerService::class);

		$scheduler->runJobs(99);
		$this->assertFalse( file_exists($data->path ) );

	}

    /**
     * @param $nonce
     * @param $formId
     * @param $control
     * @param $fieldId
     * @return \WP_REST_Request
     */
    protected function createFileRequest($nonce, $formId, $control, $fieldId)
    {
        $request = new \WP_REST_Request('POST', '/cf-api/v3/file');
        $request->set_file_params(
            array(
                'files' => array(
                    'file' => file_get_contents($this->test_file),
                    'name' => 'screenshot.jpeg',
                    'size' => filesize($this->test_file),
                    'tmp_name' => $this->test_file,
                ),
            )
        );
        $request->set_param('verify', $nonce);
        $request->set_param('formId', $formId);
        $request->set_param('control', $control);
        $request->set_param('fieldId', $fieldId);
        $request->set_param('hashes', [
            0 => md5_file($this->test_file)
        ]);
        return $request;
    }


}
