<?php

namespace App\Controllers\Admin;

use App\Libraries\Log\Log;
use App\Models\HPILOModel;
use App\Entities\HPILOEntity;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Libraries\API\HPILO\HPILO4;

class HPILOController extends \App\Controllers\Admin\AdminController
{
    private $_adapter = null;
    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->_className .= '/HPILO';
        $this->_model = new HPILOModel();
        $this->_defines = [
            'insert' => [
                'fields' => ['customer', 'id', 'passwd', 'ip', 'port', 'status'],
                'fieldFilters'  => ['status'],
                'fieldRules' => [
                    'customer'          => 'required|min_length[4]|max_length[100]',
                    'id'                => 'required|min_length[4]|max_length[20]',
                    'passwd'            => 'required|trim|min_length[4]|max_length[150]',
                    'ip'                => 'required|trim|min_length[4]|max_length[50]',
                    'port'              => 'required|min_length[2]|max_length[20]',
                ]
            ],
            'update' => [
                'fields' => ['customer', 'id', 'passwd', 'ip', 'port', 'status'],
                'fieldFilters'  => ['status'],
                'fieldRules' => [
                    'customer'          => 'required|min_length[4]|max_length[100]',
                    'id'                => 'required|min_length[4]|max_length[20]',
                    'passwd'            => 'required|trim|min_length[4]|max_length[150]',
                    'ip'                => 'required|trim|min_length[4]|max_length[50]',
                    'port'              => 'required|min_length[2]|max_length[20]',
                ]
            ],
            'view' => [
                'fields' => ['customer', 'id', 'ip', 'port', 'model', 'processor', 'memory', 'health', 'power', 'detail', 'status', 'updated_at', 'created_at'],
                'fieldFilters'  => ['status'],
                'fieldRules' => [],
            ],
            'index' => [
                'fields' => ['customer', 'ip', 'port', 'model', 'processor', 'memory', 'health', 'power', 'status', 'created_at'],
                'fieldFilters'  => ['power', 'status'],
                'batchjobFilters' => [],
            ],
            'excel' => [
                'fields' => ['customer', 'ip', 'port', 'model', 'processor', 'memory', 'health', 'power', 'status', 'created_at'],
                'fieldFilters'  => ['status'],
            ],
        ];
        helper($this->_className);
        $this->_viewPath = strtolower($this->_className);
        $this->_viewDatas['title'] = lang($this->_className . '.title');
        $this->_viewDatas['className'] = $this->_className;
    }

    private function getAdapter(HPILOEntity $entity)
    {
        if (is_null($this->_adapter)) {
            $adapterClass = getenv('hpilo.api.adapter') ? getenv('hpilo.api.adapter') : "\App\Libraries\Log\GuzzleAdapter";
            $this->_adapter = new $adapterClass($entity, getenv('hpilo.api.debug') ? getenv('hpilo.api.debug') : false);
        }
        return $this->_adapter;
    }

    //Insert관련
    protected function insert_validate()
    {
        parent::insert_validate();
        //IP형식 검사 모든 ip형식 사용가능
        if (!isIPAddress_CommonHelper($this->_viewDatas['fieldDatas']['ip'], 'all')) {
            throw new \Exception("{$this->_viewDatas['title']}의 all, {$this->_viewDatas['fieldDatas']['ip']} 형식 오류");
        }
    }

    ////Action 모음
    //Insert관련
    final public function insert()
    {
        return $this->insert_procedure();
    }
    //Update관련
    final public function update($uid)
    {
        return $this->update_procedure($uid);
    }
    //Toggle관련
    final public function toggle($uid, string $field)
    {
        return $this->toggle_procedure($uid, $field);
    }
    //Batchjob 관련
    final public function batchjob()
    {
        return $this->batchjob_procedure();
    }
    //Delete 관련
    final public function delete($uid)
    {
        return $this->delete_procedure($uid);
    }
    //View 관련
    final public function view($uid)
    {
        return $this->view_procedure($uid);
    }
    //Index 관련
    final public function index()
    {
        return $this->index_procedure();
    }
    //Excel 관련
    final public function excel()
    {
        return $this->excel_procedure();
    }
    ////추가 Action
    final public function console(int $uid)
    {
        $entity = $this->_model->getEntity($uid);
        $ilo = new HPILO4($this->getAdapter($entity));
        $this->_viewDatas['SessionKey'] = $ilo->console();
        $this->_viewDatas['entity'] = $entity;
        return view($this->_viewPath . '/console_iframe', $this->_viewDatas);
    }
    private function refresh(HPILO4 $ilo, HPILOEntity $entity)
    {
        $entity = $ilo->refresh($entity);
        if ($entity->hasChanged()) {
            if (!$this->_model->save($entity)) {
                Log::add("error", __FUNCTION__ . "에서 호출:" . $this->_model->getLastQuery());
                Log::add("error", implode("\n", $this->_model->errors()));
                throw new \Exception(__FUNCTION__ . " 오류 발생.\n" . var_export($this->_model->errors(), true));
            }
        }
        return $entity;
    }
    final public function reset(int $uid, string $type)
    {
        try {
            $entity = $this->_model->getEntity($uid);
            if (!in_array($type, ["On", "Off", "Restart"])) {
                throw new \Exception(__FUNCTION__ . "에서 {$type}은 기능은 없습니다.");
            }
            $ilo = new HPILO4($this->getAdapter($entity));
            $results = $ilo->reset($type);
            Log::add("warning", var_export($results, true));
            // sleep(DEFAULT_RERESH_WAITTIME);
            // $entity = $this->refresh($ilo, $entity);
            $message = "{$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.";
            Log::save("{$this->_viewDatas['title']} {$message}");
            return alert_CommonHelper($message, session()->get(LOGINS['RETURN_URL']));
        } catch (\Exception $e) {
            $message = "{$entity->getTitle()} " . __FUNCTION__ . " 실패하였습니다.";
            Log::add("warning", $message . "<br>\n{$e->getMessage()}");
            Log::save("{$this->_viewDatas['title']} {$message}", false);
            return alert_CommonHelper($message, 'back');
        }
    }
    final public function reload(int $uid)
    {
        try {
            $entity = $this->_model->getEntity($uid);
            $ilo = new HPILO4($this->getAdapter($entity));
            // throw new \Exception(var_export($ilo, true));
            $entity = $this->refresh($ilo, $entity);
            $message = "{$entity->getTitle()} " . __FUNCTION__ . " 완료하였습니다.";
            Log::save("{$this->_viewDatas['title']} {$message}");
            return alert_CommonHelper($message, session()->get(LOGINS['RETURN_URL']));
        } catch (\Exception $e) {
            $message = "{$entity->getTitle()} " . __FUNCTION__ . " 실패하였습니다.";
            Log::add("warning", $message . "<br>\n{$e->getMessage()}");
            Log::save("{$this->_viewDatas['title']} {$message}", false);
            return alert_CommonHelper($message, 'back');
        }
    }
}
