<?php

namespace Drupal\Tests\dkan_dataset_archiver\Unit\Controller;

use Drupal\Core\File\FileSystem;
use Drupal\dkan_dataset_archiver\Controller\FileZipController;
use Drupal\metastore_search\Search;
use MockChain\Chain;
use MockChain\Options;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * FileZipControllerTest for testing the FileZipController.
 */
class FileZipControllerTest extends TestCase {

  /**
   * Test the main functionality of the zipper registration.
   */
  public function test() {

    $fileZipController = $this->getMockFileZipController([
      "theme" => "theme_value",
      "fulltext" => "fulltext_value",
    ]);

    [$finalFilename, $cleanUrls] = $fileZipController->datasetZipper(TRUE);

    $expectedCleanUrls = [
      '/tmp/ziptest/resources/asdf2/asdf3.txt.zip',
      '/tmp/ziptest/resources/asdf8/asdf9.txt.zip',
    ];

    $expectedFilename = 'filtered-search-results.zip';
    $this->assertEquals($expectedCleanUrls, $cleanUrls);
    $this->assertEquals($expectedFilename, $finalFilename);
  }

  /**
   * Test the main functionality of the zipper registration.
   */
  public function testWithFilename() {

    $fileZipController = $this->getMockFileZipController([
      "theme" => "theme_value",
      "fulltext" => "fulltext_value",
      "filename" => "hello!!!",
    ]);

    [$finalFilename, $cleanUrls] = $fileZipController->datasetZipper(TRUE);

    $expectedCleanUrls = [
      '/tmp/ziptest/resources/asdf2/asdf3.txt.zip',
      '/tmp/ziptest/resources/asdf8/asdf9.txt.zip',
    ];

    $expectedFilename = 'hello-filtered-search-results.zip';
    $this->assertEquals($expectedCleanUrls, $cleanUrls);
    $this->assertEquals($expectedFilename, $finalFilename);
  }

  /**
   * Test the main functionality of the zipper registration.
   */
  public function testNoSearchInfo() {

    $fileZipController = $this->getMockFileZipController([]);

    [$finalFilename, $cleanUrls] = $fileZipController->datasetZipper(TRUE);

    $expectedCleanUrls = [];

    $expectedFilename = 'filtered-search-results.zip';
    $this->assertEquals($expectedCleanUrls, $cleanUrls);
    $this->assertEquals($expectedFilename, $finalFilename);
  }

  /**
   * Helper function for getting Mock objects.
   *
   * @param object $queryObject
   *   The temp folder to use.
   *
   * @return Drupal\dkan_dataset_archiver\Controller\FileZipController
   *   An array of the Mock FileZipController.
   */
  public function getMockFileZipController($queryObject) {
    $searchResult = (object) [
      'results' => [
        (object) [
          'distribution' => [
            (object) ['downloadURL' => "asdf1/asdf2/asdf3.txt"],
          ],
        ],
        (object) [
          'distribution' => [
            (object) ['downloadURL' => "asdf4/asdf5/asdf6.txt"],
          ],
        ],
        (object) [
          'distribution' => [
            (object) ['downloadURL' => "asdf7/asdf8/asdf9.txt"],
          ],
        ],
        (object) [
          'distribution' => [
            (object) ['downloadURL' => "./asdf10/asdf11/asdf12.txt"],
          ],
        ],
      ],
    ];

    $options = (new Options())
      ->add('file_system', FileSystem::class)
      ->add('request_stack', RequestStack::class)
      ->add('dkan.metastore_search.service', Search::class)
      ->add('entity_type.manager', EntityTypeManager::class)
      ->index(0);

    $request = new Request($queryObject);
    $container = (new Chain($this))
      ->add(ContainerInterface::class, 'get', $options)
      ->add(RequestStack::class, 'getCurrentRequest', $request)
      ->add(FileSystem::class, 'realpath', '/tmp/ziptest')
      ->add(Search::class, 'search', $searchResult);

    return FileZipController::create($container->getMock());
  }

  /**
   * Remove all assets added by the test.
   */
  protected function setUp(): void {
    mkdir('/tmp/ziptest');
    mkdir('/tmp/ziptest/resources');
    mkdir('/tmp/ziptest/resources/asdf2');
    mkdir('/tmp/ziptest/resources/asdf8');

    touch('/tmp/ziptest/resources/asdf2/asdf3.txt.zip');
    touch('/tmp/ziptest/resources/asdf8/asdf9.txt.zip');
  }

  /**
   * Remove all assets added by the test.
   */
  protected function tearDown(): void {
    if (is_dir("/tmp/ziptest")) {
      `rm -r /tmp/ziptest`;
    }
  }

}
