<?php

declare(strict_types=1);

namespace Drupal\Tests\farm_import_csv\Functional;

use Drupal\Tests\farm_test\Functional\FarmBrowserTestBase;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Tests the farmOS CSV importers.
 */
#[Group('farm')]
#[RunTestsInSeparateProcesses]
class CsvImportTest extends FarmBrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'farm_import_csv_test',
  ];

  /**
   * Test CSV controllers and access.
   */
  public function testCsvControllers() {

    // Create and login a test user with no permissions.
    $user = $this->createUser();
    $this->drupalLogin($user);

    // Go to the CSV importer index and confirm that access is denied.
    $this->drupalGet('import/csv');
    $this->assertSession()->statusCodeEquals(403);

    // Create and login a test user with access to view importers.
    $user = $this->createUser(['access farm import index']);
    $this->drupalLogin($user);

    // Go to the CSV importer index and confirm that access is granted, but no
    // importers are visible.
    $this->drupalGet('import/csv');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('You do not have any importers.');

    // Go to the individual log importers and confirm that access is denied.
    $this->drupalGet('import/csv/csv_asset:equipment');
    $this->assertSession()->statusCodeEquals(403);
    $this->drupalGet('import/csv/csv_log:harvest');
    $this->assertSession()->statusCodeEquals(403);
    $this->drupalGet('import/csv/csv_taxonomy_term:animal_type');
    $this->assertSession()->statusCodeEquals(403);

    // Create and login a test user with access to the CSV importer index, and
    // permission to create equipment assets, harvest logs, and animal type
    // terms.
    $user = $this->createUser([
      'access farm import index',
      'create equipment asset',
      'create harvest log',
      'create terms in animal_type',
    ]);
    $this->drupalLogin($user);

    // Go to the CSV importer index and confirm that access is granted and the
    // individual importers are visible.
    $this->drupalGet('import/csv');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('Asset: Equipment');
    $this->assertSession()->pageTextContains('Log: Harvest');
    $this->assertSession()->pageTextContains('Taxonomy Term: Animal type');

    // Go to the harvest log importer and confirm that access is granted and
    // the title is visible.
    $this->drupalGet('import/csv/csv_log:harvest');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('Import Log: Harvest');

    // Go to the asset, log, and term importers and confirm that column
    // descriptions are included, along with a link to download a template.
    $this->drupalGet('import/csv/csv_asset:equipment');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('Download template');
    $columns = [
      'name: Name of the asset. Required.',
      'parents: Parents of the asset. Accepts asset names, ID tags, UUIDs, and IDs. Multiple assets can be separated by commas with the whole cell wrapped in quotes.',
      'notes: Notes about the asset.',
      'flags: Flags for sorting and filtering. Multiple flags can be separated by commas with the whole cell wrapped in quotes.',
      'is location: Whether this asset is a location. Accepts most boolean values. Leave this blank to use the default for this asset type.',
      'is fixed: Whether this asset has a fixed location. Accepts most boolean values. Leave this blank to use the default for this asset type.',
      'intrinsic geometry: The intrinsic geometry of the asset in WKT format. This is only used if the asset has a fixed location.',
      'archived: Whether the asset is archived.',
      'id tag: ID tag.',
      'id tag type: The type of ID tag. Allowed values: eid, other.',
      'id tag location: Location of the ID tag.',
      'equipment type: Enter the type of equipment. Multiple values can be separated by commas with the whole cell wrapped in quotes.',
      'manufacturer',
      'model',
      'serial number',
    ];
    foreach ($columns as $description) {
      $this->assertSession()->pageTextContains($description);
    }
    $this->drupalGet('import/csv/csv_log:harvest');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('Download template');
    $columns = [
      'name: Name of the log.',
      'timestamp: Timestamp of the log. Accepts most date/time formats. Required.',
      'assets: Assets referenced by the log. Accepts asset names, ID tags, UUIDs, and IDs. Multiple assets can be separated by commas with the whole cell wrapped in quotes.',
      'locations: Location assets where the log took place. Accepts asset names, ID tags, UUIDs, and IDs. Multiple assets can be separated by commas with the whole cell wrapped in quotes.',
      'quantity: Numeric quantity value.',
      'quantity measure: Measure of the quantity. Allowed values: count, length, weight, area, volume, time, temperature, pressure, water_content, value, rate, rating, ratio, probability, speed',
      'quantity units: Units of measurement of the quantity. A new term in the units taxonomy will be created if necessary.',
      'quantity label: Label of the quantity.',
      'notes: Notes about the log.',
      'categories: Log category taxonomy terms. Multiple terms can be separated by commas with the whole cell wrapped in quotes.',
      'flags: Flags for sorting and filtering. Multiple flags can be separated by commas with the whole cell wrapped in quotes.',
      'geometry: The geometry of the log in WKT format.',
      'is movement: Whether this log represents an asset movement. Accepts most boolean values. Leave this blank to use the default for this log type.',
      'status: Status of the log.',
      'equipment: What equipment was used? Accepts asset names, ID tags, UUIDs, and IDs. Multiple values can be separated by commas with the whole cell wrapped in quotes.',
      'lot number: If this harvest is part of a batch or lot, enter the lot number here.',
      'test string',
    ];
    foreach ($columns as $description) {
      $this->assertSession()->pageTextContains($description);
    }
    $this->assertSession()->pageTextNotContains('excluded test string');
    $this->drupalGet('import/csv/csv_taxonomy_term:animal_type');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('Download template');
    $columns = [
      'name: Name of the term. Required.',
      'description: Description of the term.',
      'parent: Parent term in the taxonomy hierarchy.',
      'test config field',
    ];
    foreach ($columns as $description) {
      $this->assertSession()->pageTextContains($description);
    }
  }

}
