<?php
namespace nur\mapper\csv;

use nur\A;
use nur\b\params\parametrable_utils;
use nur\b\params\Tparametrable;
use nur\b\ValueException;
use nur\mapper\base\Mapper;

abstract class AbstractCsvMapper extends Mapper {
  use Tparametrable;

  const SEPARATOR = csv_defaults::OO_SEPARATOR;
  const ENCLOSURE = csv_defaults::OO_ENCLOSURE;
  const ESCAPE = csv_defaults::OO_ESCAPE;

  function __construct(?iterable $source=null) {
    parent::__construct($source);
    $this->separator = static::SEPARATOR;
    $this->enclosure = static::ENCLOSURE;
    $this->escape = static::ESCAPE;
  }

  const PARAMETRABLE_PARAMS_SCHEMA = [
    "csv_flavour" => [null, null, "type de fichier CSV: excel ou ooffice"],
    "multi_schema" => ["bool", false, "les flux multi-schémas sont-ils supportés?"],
  ];

  protected $separator;
  protected $enclosure;
  protected $escape;

  function getCsvFlavour(): array {
    return [$this->separator, $this->enclosure, $this->escape];
  }

  /** @param $csvFlavour string|array */
  function pp_setCsvFlavour($csvFlavour): void {
    if ($csvFlavour === null) {
      $csvFlavour = [static::SEPARATOR, static::ENCLOSURE, static::ESCAPE];
    }
    if (is_string($csvFlavour)) {
      $csvFlavour = csv_defaults::verifix_name($csvFlavour);
      switch ($csvFlavour) {
      case csv_defaults::OO_NAME:
        $csvFlavour = csv_defaults::OO_FLAVOUR;
        break;
      case csv_defaults::XL_NAME:
        $csvFlavour = csv_defaults::XL_FLAVOUR;
        break;
      default:
        if (strlen($csvFlavour) <= 3) {
          $separator = substr($csvFlavour, 0, 1);
          if (!$separator) $separator = static::SEPARATOR;
          $enclosure = substr($csvFlavour, 1, 1);
          if (!$enclosure) $enclosure = static::ENCLOSURE;
          $escape = substr($csvFlavour, 2, 1);
          if (!$escape) $escape = static::ESCAPE;
          $csvFlavour = [$separator, $enclosure, $escape];
        }
        break;
      }
    }
    if (is_array($csvFlavour)) {
      [$this->separator, $this->enclosure, $this->escape] = $csvFlavour;
    } else {
      throw ValueException::invalid_value($csvFlavour, "csv flavour");
    }
  }

  /** @param $csvFlavour string|array */
  function setCsvFlavour($csvFlavour): self {
    $this->pp_setCsvFlavour($csvFlavour);
    return $this;
  }

  /** @var bool les fichiers avec plusieurs schémas sont-ils supportés? */
  protected $ppMultiSchema;

  function setMultiSchema(bool $multiSchema=true): self {
    $this->ppMultiSchema = $multiSchema;
    return $this;
  }
}