<?php

class Job extends PhonalisaRecord
{

    // JobTypes
    const NoSet = 0;
    const Provisioning = 1;
    const NetworkScan = 2;
    const AddPhoneToProvisioning = 3;
    const AddressImport = 4;
    const Cleanup = 5;
    const LDAPImport = 6;
    const CallProtectionImport = 7;
    //JobState
    const Inserted = 0;
    const Triggered = 1;
    const Running = 2;
    const Finished = 3;
    const NeedToTriggerAgain = 4;
    const Failed = 5;

    public $type;
    public $user_id;
    public $phone_extension;
    public $phone_id;
    public $meta;
    public $status = Job::Inserted;
    public $errorText;
    public $progress;

    public function getTypeAsString($data)
    {
        return Job::getTypesHumanReadable($data->type);
    }

    public function getTypesHumanReadable($type)
    {
        $typeAsString = __('JOB_TYPE_UNDEFINED');
        if ($type == Job::NoSet) {
            $typeAsString = __('JOB_TYPE_NOSET');
        } else if ($type == Job::Provisioning) {
            $typeAsString = __('JOB_TYPE_PROVISIONING');
        } else if ($type == Job::NetworkScan) {
            $typeAsString = __('JOB_TYPE_NETWORKSCAN');
        } else if ($type == Job::AddPhoneToProvisioning) {
            $typeAsString = __('JOB_TYPE_ADD_TO_PROVISIONING');
        } else if ($type == Job::AddressImport) {
            $typeAsString = __('JOB_TYPE_ADDRESS_IMPORT');
        } else if ($type == Job::Cleanup) {
            $typeAsString = __('JOB_TYPE_CLEANUP');
        } else if ($type == Job::LDAPImport) {
            $typeAsString = __('JOB_TYPE_LDAP_IMPORT');
        } else if ($type == Job::CallProtectionImport) {
            $typeAsString = __('JOB_TYPE_CALL_PROTECTION_IMPORT');
        }
        return $typeAsString;
    }

    public static function myAttributes()
    {
        return array(
            'type' => 'type',
            'user_id' => 'user_id',
            'phone_id' => 'phone_id',
            'meta' => 'meta',
            'status' => 'status',
            "errorText" => "errorText",
            'phone_extension' => 'phone_extension',
            "progress" => "progress"
        );
    }

    /**
     * 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 string the associated database table name
     */
    public function tableName()
    {
        return 'job';
    }

    /**
     * @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(
            array('type', 'required'),
            array('phone_extension, type, user_id, phone_id, progress', 'length', 'max' => 255),
            array('status', 'length', 'max' => 1),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('type, user_id, meta, status', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'user_id' => __('JOBS_MODEL_USER_ID'),
            'type' => __('JOB_MODEL_TYPE'),
            'meta' => __('JOB_MODEL_META'),
            'phone_id' => __('JOB_MODEL_PHONE_ID'),
            'status' => __('JOB_MODEL_STATUS'),
            'phone_extension' => __('EXTENSION'),
            "progress" => __("JOB_PROGRESS")
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CPhonalisaDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search($order = 'type')
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;
        $filter = $this->getFilter($criteria, $order);

        $filter['pagination'] = array(
            'pageSize' => getGridPageSize('job-grid'),
        );

        if ($filter != null) {
            return new CPhonalisaDataProvider($this, $filter);
        }
        /*
          $criteria->compare('user_id',$this->user_id);
          $criteria->compare('phone_id',$this->phone_id);
          $criteria->compare('type',$this->type);
          $criteria->compare('meta',$this->meta);

          return new CPhonalisaDataProvider($this, array(
          'criteria'=>$criteria,
          )); */
    }

    public function setType($type)
    {
        $this->type = $type;
    }

    public function getFormattedPhoneIp($data)
    {
        if ($data->phone_id) {
            return $this->getIpFromPhoneModel($data->phone_id);
        } else if ($data->meta) {
            return $this->getIpFromScanResult($data->meta);
        }
    }

    public function getIpFromPhoneModel($phoneId)
    {
        $phone = Phones::model()->findByPk($phoneId);
        if ($phone == NULL) {
            return __('PHONE_NOT_FOUND');
        }

        $sipAccount = $phone->getSipAccount();
        $phoneName = $phone->ipv4_address . ' ' . $phone->name;

        if ($sipAccount == NULL) {
            return $phoneName;
        }
        return $phoneName . ' <' . $sipAccount->authname . '>';
    }

    public function getIpFromScanResult($scanResultId)
    {
        $networkScanresult = NetworkScanResult::model()->findByPk($scanResultId);
        if ($networkScanresult) {
            $ip = $networkScanresult->ipv4 . " (" . $networkScanresult->vendor . ")";
            return $ip;
        }
        return __('PHONE_NOT_FOUND');
    }

    public function getTypeFilterData()
    {
        return array(
            Job::NoSet => $this->getTypesHumanReadable(Job::NoSet),
            Job::Provisioning => $this->getTypesHumanReadable(Job::Provisioning),
            Job::NetworkScan => $this->getTypesHumanReadable(Job::NetworkScan),
            Job::AddPhoneToProvisioning => $this->getTypesHumanReadable(Job::AddPhoneToProvisioning)
        );
    }

    public function getStatusFilterData()
    {
        return array(
            Job::Inserted => __('JOB_STATUS_INSERTED'),
            Job::Triggered => __('JOB_STATUS_TRIGGERED'),
            Job::Running => __('JOB_STATUS_RUNNING'),
            Job::Finished => __('JOB_STATUS_FINNISHED'),
            Job::NeedToTriggerAgain => __('JOB_STATUS_NEED_TO_TRIGGER_AGAIN'),
            Job::Failed => __('JOB_STATUS_FAILED')
        );
    }

    public function setJsonMeta($limit, $offset, $thirdPartyCredentialId, $totalItemCount, $progress)
    {
        $this->meta = json_encode(array(
            "limit" => $limit,
            "offset" => $offset,
            "thirdPartyCredentialId" => $thirdPartyCredentialId,
            "totalItemCount" => $totalItemCount,
            "progress" => $progress,
        ));
    }

    public function getJsonMeta()
    {
        if (!$this->meta) {
            throw new CHttpException(404, "No Meta data found for Job ID $this->id");
        }
        return json_decode($this->meta);
    }

    public function beforeDelete()
    {
        if ($this->type == Job::CallProtectionImport) {
            $this->changeScoreListEntryStatus();
        }
        return parent::beforeDelete();
    }

    private function changeScoreListEntryStatus()
    {
        $model = ScoreListEntryStatus::model()->findByAttributes(array());
        if ($model) {
            $model->status = 'error';
            if ($this->status == Job::Finished) {
                $model->status = 'ok';
            }
            $model->save();
        }
    }
}
