<?php

namespace Drupal\Tests\dkan_metastore\Unit;

use Drupal\Core\DependencyInjection\Container;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\dkan_metastore\SchemaRetriever;
use Drupal\Tests\dkan_common\Traits\ServiceCheckTrait;
use MockChain\Chain;
use MockChain\Options;
use PHPUnit\Framework\TestCase;

/**
 * Tests Drupal\schema\SchemaRetriever.
 *
 * @coversDefaultClass \Drupal\dkan_metastore\SchemaRetriever
 * @group harvest
 */
class SchemaRetrieverTest extends TestCase {
  use ServiceCheckTrait;

  const APP_ROOT = __DIR__ . '/../files';

  /**
   * Protected.
   */
  protected function setUp(): void {
    // TODO: Change the autogenerated stub.
    parent::setUp();
    if (!defined("DRUPAL_MINIMUM_PHP")) {
      define("DRUPAL_MINIMUM_PHP", "7.0");
    }
  }

  /**
   *
   */
  public function testSchemaDirectory() {
    $retriever = $this->getSchemaRetriever();
    $dir = $retriever->getSchemaDirectory();
    $appRoot = self::APP_ROOT;
    $this->assertEquals($dir, "{$appRoot}/schema");
  }

  /**
   *
   */
  public function testGetAllIds() {
    $retriever = $this->getSchemaRetriever();
    $ids = $retriever->getAllIds();
    $expected = [
      'catalog',
      'dataset',
      'dataset.ui',
      'publisher',
      'publisher.ui',
      'distribution',
      'distribution.ui',
      'theme',
      'theme.ui',
      'keyword',
      'keyword.ui',
      'data-dictionary',
    ];
    $this->assertEquals($expected, $ids);
  }

  /**
   *
   */
  public function testGet() {
    $retriever = $this->getSchemaRetriever();
    $schema = $retriever->retrieve('dataset');
    $json = json_decode((string) $schema);
    $this->assertNotFalse($json);
  }

  /**
   *
   */
  public function testError() {
    $this->expectExceptionMessage("Schema blah not found.");
    $retriever = $this->getSchemaRetriever();
    $retriever->retrieve('blah');
  }

  /**
   *
   */
  public function testNoDirectory() {
    $this->expectExceptionMessage("No schema directory found.");
    $retriever = $this->getSchemaRetriever(TRUE);
    $retriever->retrieve('dataset');
  }

  /**
   * Private.
   */
  private function getSchemaRetriever($badRoot = FALSE) {
    if ($badRoot) {
      $appRoot = "tmp";
    }
    else {
      $appRoot = self::APP_ROOT;
    }

    $options = (new Options())
      ->add('extension.list.module', ModuleExtensionList::class)
      ->index(0);

    $chain = (new Chain($this))
      ->add(Container::class, 'getParameter', $appRoot)
      ->add(Container::class, 'get', $options)
      ->add(ModuleExtensionList::class, 'getPathname', "tmp");

    return SchemaRetriever::create($chain->getMock());
  }

}
