<?php
namespace nur\sery\db\cache;

use Closure;
use IteratorAggregate;
use nur\sery\cl;
use nur\sery\db\CapacitorChannel;
use Traversable;

class RowsChannel extends CapacitorChannel implements IteratorAggregate {
  const COLUMN_DEFINITIONS = [
    "key" => "varchar(128) primary key not null",
    "all_values" => "mediumtext",
  ];

  function __construct($id, callable $builder, ?string $duration=null) {
    $this->cacheIds = $cacheIds = CacheChannel::get_cache_ids($id);
    $this->builder = Closure::fromCallable($builder);
    $this->duration = $duration;
    $name = "{$cacheIds["group_id"]}-{$cacheIds["id"]}";
    parent::__construct($name);
  }

  protected array $cacheIds;

  protected Closure $builder;

  protected ?string $duration = null;

  function getItemValues($item): ?array {
    $key = array_keys($item)[0];
    $row = $item[$key];
    return [
      "key" => $key,
      "item" => $row,
      "all_values" => implode(" ", cl::filter_n(cl::with($row))),
    ];
  }

  function getIterator(): Traversable {
    $cm = cache::get();
    if ($cm->shouldUpdate($this->cacheIds)) {
      $this->capacitor->reset();
      foreach (($this->builder)() as $key => $row) {
        $this->charge([$key => $row]);
      }
      $cm->setCached($this->cacheIds, $this->duration);
    }
    return $this->discharge(false);
  }
}
