<?php

namespace App\Libraries\Cloudflare\API;

class Record 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\RecordModel();
  }
  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 'Record';
  }
  protected function getEntityByResult(\stdClass $cfResult): \App\Entities\Cloudflare\API\RecordEntity
  {
    // throw new \Exception(var_export($cfResult, true));
    $entity = is_null($this->_entity) ? new \App\Entities\Cloudflare\API\RecordEntity() : $this->_entity;
    // throw new \Exception(var_export($cfResult, true));
    $entity->uid = $cfResult->id;
    $entity->zone_uid = $cfResult->zone_id;
    $entity->host = $cfResult->name;
    $entity->type = $cfResult->type;
    $entity->content = $cfResult->content;
    $entity->ttl = $cfResult->ttl;
    $entity->proxiable = $cfResult->proxiable ? "on" : "off";
    $entity->proxied = $cfResult->proxied ? "on" : "off";
    $entity->locked = $cfResult->locked ? "off" : "on";
    // $entity->updated_at = $cfResult->modified_on;
    $entity->created_at = $cfResult->created_on;
    // throw new \Exception(var_export($cfResult, true));
    return $entity;
  }

  public function insert(array $fieldDatas): \App\Entities\Cloudflare\API\RecordEntity
  {
    //TTL값은 CDN(proxied)가 사용함일때는 무조건 1, 않함일때는 120이 적용
    $options = [
      'name' => $fieldDatas['host'],
      'type' => $fieldDatas['type'],
      'content' => $fieldDatas['content'],
      'proxied' => isset($fieldDatas['proxied']) && $fieldDatas['proxied'] === 'on' ? true : false
    ];
    // throw new \Exception(var_export($options, true));
    $cfResult = $this->getAdapter()->post('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records', $options);
    $cfResult = json_decode($cfResult->getBody());
    if (!$cfResult->success) {
      throw new \Exception(var_export($cfResult, true));
    }
    return $this->getEntityByResult($cfResult->result);
  }
  public function update(\App\Entities\Cloudflare\API\RecordEntity $entity, array $fieldDatas): \App\Entities\Cloudflare\API\RecordEntity
  {
    //TTL값은 CDN(proxied)가 사용함일때는 무조건 1, 않함일때는 120이 적용
    $options = [
      'type' => isset($fieldDatas['type']) ? $fieldDatas['type'] : $entity->type,
      'name' => isset($fieldDatas['host'])  ? $fieldDatas['host'] : $entity->host,
      'content' => isset($fieldDatas['content']) ? $fieldDatas['content'] : $entity->content,
      'proxied' => isset($fieldDatas['proxied']) && $fieldDatas['proxied'] === 'on' ? true : false
    ];
    if (isset($entity->ttl) && $entity->ttl > 0) {
      $options['ttl'] = $options['proxied'] ? 1 : 120;
    }
    // throw new \Exception(var_export($fieldDatas, true) . "<HR>" . var_export($options, true));
    $cfResult = $this->getAdapter()->put('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records/' . $entity->getPrimaryKey(), $options);
    $cfResult = json_decode($cfResult->getBody());
    if (!$cfResult->success) {
      throw new \Exception(var_export($cfResult, true));
    }
    return $this->getEntityByResult($cfResult->result);
  }
  public function deleteByZone()
  {
    $this->_model->where($this->_model::PARENT_FIELD, $this->getParent()->getPrimaryKey())->delete();
  }
  public function delete(\App\Entities\Cloudflare\API\RecordEntity $entity)
  {
    $cfResult = $this->getAdapter()->delete('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records/' . $entity->getPrimaryKey());
    $cfResult = json_decode($cfResult->getBody());
    if (!$cfResult->success) {
      throw new \Exception(var_export($cfResult, true));
    }
  }
  public function sync(\App\Entities\Cloudflare\API\RecordEntity $entity): \App\Entities\Cloudflare\API\RecordEntity
  {
    $cfResult = $this->getAdapter()->get('zones/' . $this->getParent()->getPrimaryKey() . '/dns_records/' . $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\DNS($this->getAdapter()) : $this->_endPoint;
    return $this->_endPoint->listRecords($this->getParent()->getPrimaryKey(), '', '', '', $page, CF_ADAPTER_PERPAGE_MAX)->result;
  }
}
