<?php

namespace app\models\mikrotik\system;

use yii\base\Model;
use Yii;

require_once 'PEAR2_Net_RouterOS-1.0.0b5.phar';

use PEAR2\Net\RouterOS;
use app\models\mikrotik\MikrotikConnect;

class Certificates extends Model {

    public $id;
    public $name;
    public $country;
    public $state;
    public $locality;
    public $organization;
    public $unit;
    public $common_name;
    public $key_size;
    public $subject_alt_name;
    public $days_valid;
    public $trusted;
    public $key_usage;
    public $serial_number;
    public $fingerprint;
    public $invalid_before;
    public $invalid_after;
    public $private_key;
    public $dsa;
    public $crl;
    public $smart_card_key;
    public $authority;
    public $ca_crl_host;
    public $ca;
    public $issued;
    public $file_name;
    public $passphrase;

    public function rules() {
        return [
            ['id', 'string'],
            ['name', 'string'],
            ['country', 'string'],
            ['state', 'string'],
            ['locality', 'string'],
            ['organization', 'string'],
            ['unit', 'string'],
            ['common_name', 'string'],
            ['key_size', 'string'],
            ['subject_alt_name', 'string'],
            ['days_valid', 'string'],
            ['trusted', 'string'],
            ['serial_number', 'string'],
            ['fingerprint', 'string'],
            ['invalid_before', 'string'],
            ['invalid_after', 'string'],
            ['private_key', 'string'],
            ['dsa', 'string'],
            ['crl', 'string'],
            ['smart_card_key', 'string'],
            ['authority', 'string'],
        ];
    }

    public function getAll() {
        $connect = MikrotikConnect::Instance();
        $getRequest = new RouterOS\Request('/certificate/getall');
        $responses = $connect->getConnection()->sendSync($getRequest);
        $return = array();
        foreach ($responses as $response) {
            if ($response->getProperty('.id') != null) {
                $c = new Certificates();
                $c->id = $response->getProperty('.id');
                $c->name = $response->getProperty('name');
                $c->ca = $response->getProperty('ca');
                $c->country = $response->getProperty('country');
                $c->state = $response->getProperty('state');
                $c->locality = $response->getProperty('locality');
                $c->organization = $response->getProperty('organization');
                $c->unit = $response->getProperty('unit');
                $c->common_name = $response->getProperty('common-name');
                $c->key_size = $response->getProperty('key-size');
                $c->subject_alt_name = $response->getProperty('subject-alt-name');
                $c->days_valid = $response->getProperty('days-valid');
                $c->trusted = $response->getProperty('trusted');
                $c->key_usage = $response->getProperty('key-usage');
                $c->serial_number = $response->getProperty('serial-number');
                $c->fingerprint = $response->getProperty('fingerprint');
                $c->invalid_before = $response->getProperty('invalid-before');
                $c->invalid_after = $response->getProperty('invalid-after');
                $c->private_key = $response->getProperty('private-key');
                $c->dsa = $response->getProperty('dsa');
                $c->crl = $response->getProperty('crl');
                $c->smart_card_key = $response->getProperty('smart-card-key');
                $c->authority = $response->getProperty('authority');
                $return[] = $c;
            }
        }
        return $return;
    }

    public function get($id) {
        $connect = MikrotikConnect::Instance();
        $getRequest = new RouterOS\Request('/certificate/print');
        $getRequest->setQuery(RouterOS\Query::where('.id', $id));
        $responses = $connect->getConnection()->sendSync($getRequest);
        foreach ($responses as $response) {
            if ($response->getProperty('.id') != null) {
                $this->id = $response->getProperty('.id');
                $this->name = $response->getProperty('name');
                $this->country = $response->getProperty('country');
                $this->state = $response->getProperty('state');
                $this->locality = $response->getProperty('locality');
                $this->organization = $response->getProperty('organization');
                $this->unit = $response->getProperty('unit');
                $this->issued = $response->getProperty('issued');
                $this->common_name = $response->getProperty('common-name');
                $this->key_size = $response->getProperty('key-size');
                $this->subject_alt_name = $response->getProperty('subject-alt-name');
                $this->days_valid = $response->getProperty('days-valid');
                $this->trusted = (($response->getProperty('trusted') == 'true') ? true : false);
                $this->key_usage = $response->getProperty('key-usage');
                $this->serial_number = $response->getProperty('serial-number');
                $this->fingerprint = $response->getProperty('fingerprint');
                $this->invalid_before = $response->getProperty('invalid-before');
                $this->invalid_after = $response->getProperty('invalid-after');
                $this->private_key = (($response->getProperty('private-key') == 'true') ? true : false);
                $this->dsa = (($response->getProperty('dsa') == 'true') ? true : false);
                $this->crl = (($response->getProperty('crl') == 'true') ? true : false);
                $this->smart_card_key = (($response->getProperty('smart-card-key') == 'true') ? true : false);
                $this->authority = (($response->getProperty('authority') == 'true') ? true : false);
            }
        }
        return;
    }

    public function sign($id) {
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/certificate/sign');
        $setRequest->setArgument('.id', $id);
        $setRequest->setArgument('name', $this->name);
        if ($this->ca_crl_host != '') {
            $setRequest->setArgument('ca-crl-host', $this->ca_crl_host);
        }
        if ($this->ca_crl_host != '') {
            $setRequest->setArgument('ca', $this->ca);
        }
        $connect->getConnection()->sendSync($setRequest);
        if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
            return $resp->getProperty('message');
        } else {
            return '1';
        }
    }

    public function update($id) {
        $c = new Certificates();
        $c->get($id);
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/certificate/set');
        $setRequest->setargument('.id', $id);
        if ($this->name != $c->name) {
            $setRequest->setargument('name', $this->name);
        }
        if ($this->country != $c->country) {
            $setRequest->setargument('country', $this->country);
        }
        if ($this->state != $c->state) {
            $setRequest->setargument('state', $this->state);
        }
        if ($this->locality != $c->locality) {
            $setRequest->setargument('locality', $this->locality);
        }
        if ($this->organization != $c->organization) {
            $setRequest->setargument('organization', $this->organization);
        }
        if ($this->unit != $c->unit) {
            $setRequest->setargument('unit', $this->unit);
        }
        if ($this->common_name != $c->common_name) {
            $setRequest->setargument('common-name', $this->common_name);
        }
        if ($this->key_size != $c->key_size) {
            $setRequest->setargument('key-size', $this->key_size);
        }
        if ($this->subject_alt_name != $c->subject_alt_name) {
            $setRequest->setargument('subject-alt-name', $this->subject_alt_name);
        }
        if ($this->days_valid != $c->days_valid) {
            $setRequest->setargument('days-valid', $this->days_valid);
        }

        if ($this->key_usage != $c->key_usage) {
            $setRequest->setargument('key-usage', $this->key_usage);
        }

        if (isset($unset)) {
            $unsetRequest = new RouterOS\Request('/certificate/unset');
            foreach ($unset as $value) {
                $unsetRequest->setArgument('.id', $id);
                $unsetRequest->setArgument('value-name', $value);
                $resp = $connect->getConnection()->sendSync($unsetRequest);
                if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
                    if (!isset($re)) {
                        $re = '';
                    } $re.= ' ' . $resp->getProperty('message');
                }
            }
        } $resp = $connect->getConnection()->sendSync($setRequest);
        if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
            if (isset($re)) {
                $re.= ' ' . $resp->getProperty('message');
            } else {
                $re = $resp->getProperty('message');
            }
        } if (isset($re)) {
            return $re;
        } else {
            return '1';
        }
    }

    public function create() {
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/certificate/add');
        if ($this->name != "") {
            $setRequest->setargument('name', $this->name);
        }
        if ($this->country != "") {
            $setRequest->setargument('country', $this->country);
        }
        if ($this->state != "") {
            $setRequest->setargument('state', $this->state);
        }
        if ($this->locality != "") {
            $setRequest->setargument('locality', $this->locality);
        }
        if ($this->organization != "") {
            $setRequest->setargument('organization', $this->organization);
        }
        if ($this->unit != "") {
            $setRequest->setargument('unit', $this->unit);
        }
        if ($this->common_name != "") {
            $setRequest->setargument('common-name', $this->common_name);
        }
        if ($this->key_size != "") {
            $setRequest->setargument('key-size', $this->key_size);
        }
        if ($this->subject_alt_name != "") {
            $setRequest->setargument('subject-alt-name', $this->subject_alt_name);
        }
        if ($this->days_valid != "") {
            $setRequest->setargument('days-valid', $this->days_valid);
        }

        if ($this->key_usage != "") {
            $setRequest->setargument('key-usage', $this->key_usage);
        }

        $resp = $connect->getConnection()->sendSync($setRequest);
        if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
            return $resp->getProperty('message');
        } else {
            return '1';
        }
    }

    public function delete($id) {
        $connect = MikrotikConnect::Instance();
        $util = new RouterOS\Util($connect->getConnection());
        $util->setMenu('/certificate');
        $util->remove(RouterOS\Query::where('.id', $id));
        return;
    }

    public function getCa() {
        $connect = MikrotikConnect::Instance();
        $getRequest = new RouterOS\Request('/certificate/getall');
        $responses = $connect->getConnection()->sendSync($getRequest);
        $return = array();
        foreach ($responses as $response) {
            if ($response->getProperty('authority') != null) {
                $return[$response->getProperty('name')] = $response->getProperty('name');
            }
        }
        return $return;
    }

    public function import() {
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/certificate/import');
        $setRequest->setargument('file-name', $this->file_name);
        $setRequest->setargument('passphrase', $this->passphrase);
        return $connect->getConnection()->sendSync($setRequest);
    }

    public function export($id) {
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/certificate/export-certificate');
        $setRequest->setArgument('.id', $id);
        $setRequest->setargument('passphrase', $this->passphrase);
        $resp = $connect->getConnection()->sendSync($setRequest);
        if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
            return $resp->getProperty('message');
        } else {
            return '1';
        }
    }

    public function getFiles() {
        $connect = MikrotikConnect::Instance();
        $getRequest = new RouterOS\Request('/file/getall');
        $responses = $connect->getConnection()->sendSync($getRequest);
        $return = array();
        foreach ($responses as $response) {
            if ($response->getProperty('.id') != null) {
                $return[$response->getProperty('name')] = $response->getProperty('name');
            }
        }
        return $return;
    }

}
