<?php
namespace ProVM\Common\Implementation;

use ProVM\Common\Factory\Model as ModelFactory;

abstract class Model implements \JsonSerializable {
  abstract public function map($data): Model;
  protected $factory;
  public function setFactory(ModelFactory $factory) {
    $this->factory = $factory;
  }
  public function __get(string $name) {
    if (!property_exists($this, $name)) {
      throw new \InvalidArgumentException($name . ' is not a property of ' . get_called_class());
    }
    return $this->$name;
  }
  public function save() {
    $filename = $this->getFilename();
    $data = json_decode(trim(file_Get_contents($filename)));
    if ($this->id === null) {
      $this->id = array_reduce($data, function($max, $item) {
        return (($max < $item->id) ? $item->id : $max);
      }, 0) + 1;
      $data []= $this->jsonSerialize();
    } else {
      foreach ($data as $i => $item) {
        if ($item->id == $this->id) {
          $data[$i] = $this->jsonSerialize();
        }
      }
    }
    $data = array_values($data);
    return (file_put_contents($filename, json_encode($data, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)) !== false);
  }
  public function delete() {
    $filename = $this->getFilename();
    $data = json_decode(trim(file_Get_contents($filename)));
    foreach ($data as $i => $item) {
      if ($item->id == $this->id) {
        unset($data[$i]);
      }
    }
    $data = array_values($data);
    return (file_put_contents($filename, json_encode($data, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)) !== false);
  }
  protected function getFilename(): string {
    $data = explode("\\", get_called_class());
    $folder = $this->factory->getFolder();
    return implode(DIRECTORY_SEPARATOR, [
      $folder,
      str_replace(' ', '_', mb_strtolower(array_pop($data))) . 's.json'
    ]);
  }
}
