<?php

namespace App\Libraries\Cloudflare\API;

use App\Libraries\Log\Log;

class Zone extends API
{
    private $_endPoint = null;
    private $_entity = null;
    private $_isGetSetting = true;
    public function __construct(\App\Entities\Cloudflare\API\AccountEntity $parent, bool $isGetSetting = true)
    {
        parent::__construct($parent);
        $this->_isGetSetting = $isGetSetting;
        $this->_model = new \App\Models\Cloudflare\API\ZoneModel();
    }
    final protected function setAdapter()
    {
        if (!is_null($this->_adapter)) {
            throw new \Exception("Adapter가 이미 지정되었습니다.");
        }
        $authModel = new \App\Models\Cloudflare\API\AuthModel();
        $auth = $authModel->getEntity($this->getParent()->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 'Zone';
    }

    //Cfzone에서 가져온 값을 zone에 setting
    protected function getEntityByResult(\stdClass $cfResult): \App\Entities\Cloudflare\API\ZoneEntity
    {
        $entity = is_null($this->_entity) ? new \App\Entities\Cloudflare\API\ZoneEntity() : $this->_entity;
        $entity->uid = $cfResult->id;
        $entity->account_uid = $cfResult->account->id;
        $entity->domain = $cfResult->name;
        $entity->status = $cfResult->status;
        //$entity->type = $cfResult->type; // full 이게있는데 뭔지 잘모름
        $entity->name_servers = 'none';
        if (isset($cfResult->name_servers)) {
            $entity->name_servers = is_array($cfResult->name_servers) ?
                implode(',', $cfResult->name_servers) : $cfResult->name_servers;
        }
        $entity->original_name_servers = 'none';
        if (isset($cfResult->original_name_servers)) {
            $entity->original_name_servers = is_array($cfResult->original_name_servers) ?
                implode(',', $cfResult->original_name_servers) : $cfResult->original_name_servers;
        }
        $entity->updated_at = $cfResult->modified_on;
        $entity->created_at = $cfResult->created_on;
        $entity->plan = $cfResult->plan->name;
        return $this->_isGetSetting ? $this->getCFSetting($entity) : $entity;
    }

    //Cfzone에서 가져온 값을 zone에 setting
    final public function getCFSetting(\App\Entities\Cloudflare\API\ZoneEntity $entity): \App\Entities\Cloudflare\API\ZoneEntity
    {
        $cfResult = $this->getAdapter()->get('zones/' . $entity->getPrimaryKey() . '/settings/');
        $cfResult = json_decode($cfResult->getBody());
        if (!$cfResult->success) {
            throw new \Exception(__FUNCTION__ . "에서 Call Error:\n" . var_export($cfResult, true));
        }
        foreach ($cfResult->result as $cfResult) {
            switch ($cfResult->id) {
                case 'development_mode':
                    $entity->development_mode = $cfResult->value;
                    break;
                case 'ipv6':
                    $entity->ipv6 = $cfResult->value;
                    break;
                case 'security_level':
                    $entity->security_level = $cfResult->value;
                    break;
            }
        }
        return $entity;
    }
    //Cfzone에 해당 키값 변경용
    final public function setCFSetting(\App\Entities\Cloudflare\API\ZoneEntity $entity, string $field, string $value): \App\Entities\Cloudflare\API\ZoneEntity
    {
        $cfResult = $this->getAdapter()->patch('zones/' . $entity->getPrimaryKey() . '/settings/' . $field, array('value' => $value));
        $cfResult = json_decode($cfResult->getBody());
        if (!$cfResult->success || $cfResult->result->id !== $field) {
            throw new \Exception(__FUNCTION__ . "에서 {$field}->{$value} 변경오류:\n" . var_export($cfResult, true));
        }
        //최종 결과값은 body->result->id='필드명',body->result->value='on/off'이런식으로 받음
        $entity->$field = $cfResult->result->value;
        Log::add("warning", "Zone API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
        return $entity;
    }

    public function insert(array $fieldDatas): \App\Entities\Cloudflare\API\ZoneEntity
    {
        //도메인생성을 위해 Cloudflare에 전송
        $options = [
            'accountId' => $this->getParent()->getPrimaryKey(),
            'name' => $fieldDatas['domain'],
            'jump_start' => false,
        ];
        $cfResult = $this->getAdapter()->post('zones/', $options);
        $cfResult = json_decode($cfResult->getBody());
        if (!$cfResult->success) {
            throw new \Exception(var_export($cfResult, true));
        }
        $entity = $this->getEntityByResult($cfResult->result);
        //아래는 추가 셋팅 ipv6 TurnOFF , //Development mode TurnOFF
        $entity = $this->setCFSetting($entity, 'ipv6', 'off');
        $entity = $this->setCFSetting($entity, 'development_mode', 'off');
        $entity = $this->setCFSetting($entity, 'security_level', 'medium');
        Log::add("warning", "Record API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
        return $entity;
    }
    public function update(\App\Entities\Cloudflare\API\ZoneEntity $entity, array $fieldDatas): \App\Entities\Cloudflare\API\ZoneEntity
    {
        //ipv6 , //development_mode , //security_level
        foreach ($fieldDatas as $field => $value) {
            $entity = $this->setCFSetting($entity, $field, $value);
        }
        Log::add("warning", "API {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
        return $entity;
    }
    public function delete(\App\Entities\Cloudflare\API\ZoneEntity $entity)
    {
        //Zone 삭제
        $cfResult = $this->getAdapter()->delete('zones/' . $entity->getPrimaryKey());
        $cfResult = json_decode($cfResult->getBody());
        if (!$cfResult->success) {
            throw new \Exception(var_export($cfResult, true));
        }
        Log::add("warning", "Zone API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
    }
    public function sync(\App\Entities\Cloudflare\API\ZoneEntity $entity): \App\Entities\Cloudflare\API\ZoneEntity
    {
        $cfResult = $this->getAdapter()->get('zones/' . $entity->getPrimaryKey());
        $cfResult = json_decode($cfResult->getBody());
        if (!$cfResult->success) {
            throw new \Exception(var_export($cfResult, true));
        }
        Log::add("warning", "Zone API: {$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.");
        return $this->getEntityByResult($cfResult->result);
    }

    protected function getCFResults_List(int $page): array
    {
        $this->_endPoint = is_null($this->_endPoint) ? new \Cloudflare\API\Endpoints\Zones($this->getAdapter()) : $this->_endPoint;
        return $this->_endPoint->listZones('', '', $page, CF_ADAPTER_PERPAGE_MAX)->result;
    }
}
