<?php

namespace App\Libraries\Cloudflare\API;

class Firewall extends API
{
  private $_endPoint = null;
  private $_entity = null;
  public function __construct(\App\Entities\Cloudflare\API\ZoneEntity $parent)
  {
    parent::__construct($parent);
    $this->_model = new \App\Models\Cloudflare\API\FirewallModel();
  }
  final protected function setAdapter()
  {
    if (!is_null($this->_adapter)) {
      throw new \Exception("Adapter가 이미 지정되었습니다.");
    }
    $accountModel = new \App\Models\Cloudflare\API\AccountModel();
    $account = $accountModel->getEntity($this->getParent()->getParentFieldData());
    $authModel = new \App\Models\Cloudflare\API\AuthModel();
    $auth = $authModel->getEntity($account->getParentFieldData());
    $apikey = new \Cloudflare\API\Auth\APIKey($auth->getAuthId(), $auth->getAuthKey());
    $this->_adapter = new \Cloudflare\API\Adapter\Guzzle($apikey);
    // throw new \Exception(var_export($this->_adapter, true));
  }
  public function getClassName()
  {
    return 'Firewall';
  }
  protected function getEntityByResult(\stdClass $cfResult): \App\Entities\Cloudflare\API\FirewallEntity
  {
    $entity = is_null($this->_entity) ? new \App\Entities\Cloudflare\API\FirewallEntity() : $this->_entity;
    $entity->uid = $cfResult->id;
    $entity->zone_uid = $this->getParent()->getPrimaryKey();
    $entity->description = $cfResult->description;
    $entity->filter_id = $cfResult->filter->id;
    $entity->filter_expression = isset($cfResult->filter->expression) && $cfResult->filter->expression ? $cfResult->filter->expression : ' ';
    $entity->filter_paused = isset($cfResult->filter->paused) && $cfResult->filter->paused ? 'on' : 'off';
    $entity->action = $cfResult->action;
    $entity->paused = $cfResult->paused ? 'off' : 'on';
    $entity->updated_at = $cfResult->modified_on;
    $entity->created_at = $cfResult->created_on;
    // parent::add_logs("notice","host:[{$cfResult->name}<>{$entity->description}] | proxied:[{$cfResult->proxied}<>{$entity->proxied}] | locked:[{$cfResult->locked}<>{$entity->locked}]");
    return $entity;
  }

  // public function insert(){ }
  public function update(\App\Entities\Cloudflare\API\FirewallEntity $entity, array $fieldDatas): \App\Entities\Cloudflare\API\FirewallEntity
  {
    $rule = array_merge(
      [
        'id' => $entity->getPrimaryKey(),
        'filter' => [
          'id' => $entity->filter_id,
          'expression' => $entity->filter_expression,
          'paused' => isset($entity->filter_paused) && $entity->filter_paused === 'on' ? true : false
        ]
      ],
      [
        'paused' => isset($entity->paused) && $entity->paused === 'on' ? false : true,
        'action' => $entity->action
      ]
    );
    if (!is_null($entity->description)) {
      $rule['description'] = $entity->description;
    }

    $cfResult = $this->getAdapter()->put('zones/' . $this->getParent()->getPrimaryKey() . '/firewall/rules/' . $entity->getPrimaryKey(), $rule);
    $cfResult = json_decode($cfResult->getBody());
    if (!$cfResult->success) {
      throw new \Exception(var_export($cfResult, true));
    }
    return $this->getEntityByResult($cfResult->result);
  }
  // public function delete(){ }
  public function sync(\App\Entities\Cloudflare\API\FirewallEntity $entity): \App\Entities\Cloudflare\API\FirewallEntity
  {
    $cfResult = $this->getAdapter()->get('zones/' . $this->getParent()->getPrimaryKey() . '/firewall/rules/' . $entity->getPrimaryKey());
    $cfResult = json_decode($cfResult->getBody());
    if (!$cfResult->success) {
      throw new \Exception(var_export($cfResult, true));
    }
    return $this->getEntityByResult($cfResult->result);
  }
  protected function getCFResults_List(int $page): array
  {
    $this->_endPoint = is_null($this->_endPoint) ? new \Cloudflare\API\Endpoints\Firewall($this->getAdapter()) : $this->_endPoint;
    return $$this->_endPoint->listFirewallRules($this->getParent()->getPrimaryKey(), $page, CF_ADAPTER_PERPAGE_MAX)->result;
  }
}
