<?php

declare(strict_types=1);

namespace Drupal\languagewire_translation_provider\api\Core\DataType;

/**
 * Data type.
 */
abstract class DataTypeAbstract implements DataTypeInterface {

  /**
   * Data structure.
   *
   * @var array
   */
  private array $structure = [];

  /**
   * Set structure.
   */
  public function setStructure(array $structure): void {
    $this->structure = $structure;
  }

  /**
   * Get structure.
   */
  protected function getStructure(?string $position = NULL): array {
    $structure = $this->structure;

    $hasPosition = $position !== NULL;
    if ($hasPosition && isset($structure[$position])) {
      return $structure[$position];
    }
    elseif ($hasPosition) {
      return [];
    }

    return $structure;
  }

  /**
   * Validate structure recursively.
   */
  protected function validateStructureRecursively(array $main, array $against): bool {
    foreach ($main as $mainKey => $mainValue) {
      $isOneLevel = is_numeric($mainKey) && is_string($mainValue);
      $isMainMultiDimensional = is_array($mainValue);

      $hasMainKey = is_string($mainKey) && array_key_exists($mainKey, $against);
      $hasMultiDimensionalKey = $hasMainKey && $isMainMultiDimensional;

      if (
            ($hasMultiDimensionalKey && !$this->validateStructureRecursively($mainValue, $against[$mainKey]))
            || ($isOneLevel && !array_key_exists($mainValue, $against))
        ) {
        return FALSE;
      }
      elseif ($hasMultiDimensionalKey || $isOneLevel || !$isMainMultiDimensional) {
        continue;
      }

      foreach ($against as $againstKey => $againstValue) {
        $evaluateArray = [$againstKey => $againstValue];

        if (is_numeric($againstKey) && is_array($againstValue)) {
          $evaluateArray = $againstValue;
        }

        if (!$this->validateStructureRecursively($mainValue, $evaluateArray)) {
          return FALSE;
        }
      }
    }

    return TRUE;
  }

}
