<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

class fieldsIntegrationTest extends \PHPUnit\Framework\TestCase
{
  /**
   * @var string[][]
   */
  private $tables;

  /**
   * @var \DBOperation
   */
  private $dbop;

  /**
   * Sets up the fixture, for example, opens a network connection.
   * This method is called before a test is executed.
   */
  protected function setUp(): void
  {
    $this->dbop = \DBOperation::getInstanceDB1();

    $structureInfo = new \DBStructureInfo();
    $tablesTxt = $structureInfo->getFieldsTxt();
    $this->tables = (new \Kufer\Web\Classes\Stream\IterableStream(preg_split('/\\n\\r|\\r\\n|\\n|\\r/', $tablesTxt)))
      ->map('\\trim')
      ->filter(\FunctionOperations::not(\FunctionOperations::argsWithPlaceholder(
        \StringOperations::class . '::startsWith',
        \FunctionOperations::placeholder(),
        '--'
      )))
      ->filter(\FunctionOperations::not(\FunctionOperations::isEmpty()))
      ->map(static function(string $str) {
        $matches = array();
        preg_match_all('/^[ \\n\\t\\r]*([A-Za-z0-9_]+)=(.*)$/', $str, $matches);

        $tableStr = $matches[1][0];
        $groups = $matches[2][0];

        return new \Kufer\Web\Classes\Addfunctions\Pair($tableStr, array_filter(\StringOperations::explodeAndTrim($groups, ';')));
      })
      ->toKeyValueArrayFromPairs();
  }

  /**
   * Tears down the fixture, for example, closes a network connection.
   * This method is called after a test is executed.
   */
  protected function tearDown(): void
  {
  }

  /**
   * @test
   */
  public function testTables()
  {
    $dboperation = \DBOperation::getInstanceDB1();
    $columnsByTableInDB = $dboperation->getColumnsOfTables(array_keys($this->tables));
    foreach ($this->tables as $name => $columnsExcpect) {
      $this->assertArrayHasKey($name, $columnsByTableInDB, "Tabelle $name in Datenbank erwartet");
      $columnsExcpect = array_map('\\StringOperations::strtolower', $columnsExcpect);

      foreach ($columnsExcpect as $column) {
        $this->assertContains($column, $columnsByTableInDB[$name], "Spalte $column in Tabelle $name erwartet");
      }
    }
  }
}
