<?php

class BannedHost extends PhonalisaRecord
{

    public $host;
    public $count;

    public static function myAttributes()
    {
        return array(
            'host' => 'host',
            'count' => 'count'
        );
    }

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Job the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('host, count', 'safe'),
        );
    }

    public function beforeSave()
    {
        if ((int) $this->count >= 10) {
            if (!$this->hostInWhitelist()) {
                $this->blockHost();
                $data = array('ip' => $this->host);
                PhonalisaCtrldConnector::firewallBlockIP($data);
                Log::w('Host "' . $this->host . '" is blocked!', 'PhonalisaFirewall');
            }
        }
        return parent::beforeSave();
    }

    protected function blockHost()
    {
        $firewallModel = new FirewallBannedHost();
        $firewallModel->ip = $this->host;
        $firewallModel->datetime = PhonalisaDate::newServerDate();
        $firewallModel->reason = 'FIREWALL_BANNED_HOST_REASON_TO_MANY_FAILED_WEBGUI_AUTH';
        $firewallModel->save();
    }

    public function increaseFaildLoginCount()
    {
        if ($this->count == '') {
            $this->count = 1;
        } else {
            (int) $this->count++;
        }
    }

    protected function hostInWhitelist()
    {
        $whitelistModels = FirewallWhitelist::model()->find(array('active' => '1'), 'id');
        foreach ($whitelistModels as $whitelistModel) {
            if ($this->host == $whitelistModel->source) {
                return true;
            }

            if ($this->cidrMatched($this->host, $whitelistModel->source)) {
                return true;
            }
        }
        return false;
    }

    public function cidrMatched($ip, $cidr)
    {
        $explodedCIDR = explode('/', $cidr);
        if (!isset($explodedCIDR[1])) {
            return false;
        }
        if (isset($explodedCIDR[1]) && strpos($explodedCIDR[1], '255') !== false) {
            $explodedCIDR[1] = $this->netmaskToCIDR($explodedCIDR[1]);
        }

        if ((ip2long($ip) & ~((1 << (32 - (int) $explodedCIDR[1])) - 1) ) === ip2long($explodedCIDR[0])) {
            return true;
        }

        return false;
    }

    protected function netmaskToCIDR($mask)
    {
        $long = ip2long($mask);
        $base = ip2long('255.255.255.255');
        return 32 - log(($long ^ $base) + 1, 2);
    }
}
