<?php

declare(strict_types=1);

namespace Drupal\Tests\flowdrop\Unit\Constants;

use Drupal\Tests\UnitTestCase;
use Drupal\flowdrop\Constants\EdgeKeys;
use Drupal\flowdrop\Constants\PortDirection;
use Drupal\flowdrop\Constants\ReservedName;

/**
 * Tests that constant values remain stable across releases.
 *
 * @group flowdrop
 */
class ConstantsContractTest extends UnitTestCase {

  /**
   * Asserts EdgeKeys constant values are stable.
   *
   * @covers \Drupal\flowdrop\Constants\EdgeKeys
   */
  public function testEdgeKeysValues(): void {
    $this->assertEquals('sourceHandle', EdgeKeys::SOURCE_HANDLE);
    $this->assertEquals('targetHandle', EdgeKeys::TARGET_HANDLE);
    $this->assertEquals('is_trigger', EdgeKeys::IS_TRIGGER);
    $this->assertEquals('is_loopback', EdgeKeys::IS_LOOPBACK);
    $this->assertEquals('branch_name', EdgeKeys::BRANCH_NAME);
    $this->assertEquals('source', EdgeKeys::SOURCE);
    $this->assertEquals('target', EdgeKeys::TARGET);
    $this->assertEquals('edge_id', EdgeKeys::EDGE_ID);
  }

  /**
   * Asserts PortDirection constant values are stable.
   *
   * @covers \Drupal\flowdrop\Constants\PortDirection
   */
  public function testPortDirectionValues(): void {
    $this->assertEquals('input', PortDirection::INPUT);
    $this->assertEquals('output', PortDirection::OUTPUT);
    $this->assertEquals('inputs', PortDirection::INPUTS);
    $this->assertEquals('outputs', PortDirection::OUTPUTS);
  }

  /**
   * Asserts ReservedName constant values are stable.
   *
   * These values are part of the API contract with the frontend
   * and must not change without a migration.
   *
   * @covers \Drupal\flowdrop\Constants\ReservedName
   */
  public function testReservedNameValues(): void {
    // Config keys.
    $this->assertEquals('dynamicInputs', ReservedName::DYNAMIC_INPUTS);
    $this->assertEquals('dynamicOutputs', ReservedName::DYNAMIC_OUTPUTS);
    $this->assertEquals('branches', ReservedName::BRANCHES);
    $this->assertEquals('instanceTitle', ReservedName::INSTANCE_TITLE);
    $this->assertEquals('instanceDescription', ReservedName::INSTANCE_DESCRIPTION);
    $this->assertEquals('nodeType', ReservedName::NODE_TYPE);

    // Port names.
    $this->assertEquals('input', ReservedName::PORT_INPUT);
    $this->assertEquals('output', ReservedName::PORT_OUTPUT);
    $this->assertEquals('trigger', ReservedName::PORT_TRIGGER);
    $this->assertEquals('active_branches', ReservedName::ACTIVE_BRANCHES);
  }

  /**
   * Asserts configSchemaOnlyParams() returns params routed to configSchema.
   *
   * @covers \Drupal\flowdrop\Constants\ReservedName::configSchemaOnlyParams
   */
  public function testConfigSchemaOnlyParams(): void {
    $keys = ReservedName::configSchemaOnlyParams();
    $this->assertContains('dynamicInputs', $keys);
    $this->assertContains('dynamicOutputs', $keys);
    $this->assertContains('branches', $keys);
    $this->assertCount(3, $keys);
  }

  /**
   * Asserts forbiddenPortNames() includes all names banned for dynamic ports.
   *
   * @covers \Drupal\flowdrop\Constants\ReservedName::forbiddenPortNames
   */
  public function testForbiddenPortNames(): void {
    $forbidden = ReservedName::forbiddenPortNames();
    $this->assertContains('dynamicInputs', $forbidden);
    $this->assertContains('dynamicOutputs', $forbidden);
    $this->assertContains('branches', $forbidden);
    $this->assertContains('input', $forbidden);
    $this->assertContains('output', $forbidden);
    $this->assertContains('trigger', $forbidden);
    $this->assertContains('active_branches', $forbidden);
    $this->assertContains('instanceTitle', $forbidden);
    $this->assertContains('instanceDescription', $forbidden);
    $this->assertContains('nodeType', $forbidden);
  }

}
