<?php

require_once APPPATH . 'libraries/Cf_REST_Controller.php';
require_once APPPATH . 'modules/dashboard/models/entities/CF_Widget.php';
require_once APPPATH . 'modules/dashboard/models/entities/CF_Alert.php';
require_once APPPATH . 'modules/dashboard/models/entities/CF_Rule.php';

/**
 * @rbacName Modify all users' alert
 * @rbacDescription View, Update, Delete
 * @rbacGroup Widgets
 * @rbacAlias widgets.alerts_admin
 */

class Alertsapi extends Cf_REST_Controller
{

    public $username = "";

    function __construct()
    {
        parent::__construct();

        $this->load->model('alerts_model');
        $this->load->driver('cache', array('adapter' => 'file'));
        $this->username = $this->session->userdata('username');
    }


    //$alertsIds - can be urlencoded comma separated list
    function alerts_get($alertsIds = '')
    {

        $filter = array();
        //$filter['username'] = $this->session->userdata('username');

        if ( ! empty($alertsIds)) {
            $alertsIds = explode(',', urldecode($alertsIds));
            $alertsIds = array_map("intval", $alertsIds);
        }

        try {
            $result = $this->alerts_model->get_alerts_with_ids($alertsIds, $filter);
            if (empty($result)) {
                $message = $this->lang->line('dashboard_alert_not_exist');
                log_message('debug', 'Failed retrieving alerts, error: ' . $message);
                respond_internal_error($message);

                return;
            }

            $json = json_encode($result);
            respond_ok($json);
        } catch (Exception $e) {
            $message = $e->getMessage();
            log_message('debug', 'Failed retrieving alerts, error: ' . $message);
            respond_internal_error($message);
        }
    }

    /**
     * Return alert + rule
     *
     *
     * @param type $alertsIds
     */
    function alertswithrule_get($alertsIds = '')
    {

        $filter = array();
        //$filter['username'] = $this->session->userdata('username');

        if ( ! empty($alertsIds)) {
            $alertsIds = explode(',', urldecode($alertsIds));
            $alertsIds = array_map("intval", $alertsIds);
        }

        try {
            $alertsList = $this->alerts_model->get_alerts_with_ids($alertsIds, $filter, array('name' => 'asc'));

            if (empty($alertsList)) {
                respond_ok();
            }

            $rulesIds = array();
            foreach ($alertsList as $item => $alertObj) {
                $ruleId = $alertObj->getRuleId();
                if ( ! empty($ruleId)) {
                    $rulesIds[] = $ruleId;
                }
            }

            // return result without rules info
            if (empty($rulesIds)) {
                $json = json_encode($alertsList);
                respond_ok($json);
            }

            $this->load->model('rules_model');
            $userFilter = array();
            //$userFilter = array('username' => $this->session->userdata('username'));
            $rulesTmp = $this->rules_model->get_rules_with_ids(array_values($rulesIds), $userFilter);

            // TODO: discuss - this is error, because in alert we have reference to the rule, but rule doesn't exist
            if (empty($rulesTmp)) {
                $json = json_encode($alertsList);
                respond_ok($json);
            }


            // join data together
            // create array where rule.id is a key
            $rules = array();
            foreach ($rulesTmp as $item => $ruleObj) {
                $rules[$ruleObj->id] = $ruleObj;
            }


            $result = array();
            $i      = 0;
            foreach ($alertsList as &$alertObj) {
                $result[$i] = (array)$alertObj;
                if ( ! empty($alertObj->ruleid) && isset($rules[$alertObj->ruleid])) {
                    $result[$i]['rule'] = (array)$rules[$alertObj->ruleid];
                }
                $i++;
            }

            $json = json_encode($result);
            respond_ok($json);
        } catch (Exception $e) {
            $message = $e->getMessage();
            log_message('debug', 'Failed retrieving alerts, error: ' . $message);
            respond_internal_error($message);
        }
    }


    /**
     * Save alert
     * Allow overwrite only by id
     * same name not allowed  - show error
     *
     *
     * @param <string> $id - id of the alert. If not provided - assume insert, if provided - assume update
     *
     * @return
     */
    function savealert_post($id = '')
    {

        $data = json_decode($this->request->body, true);

        $data['username'] = $this->session->userdata('username');
        $is_admin         = isActionAllowed('widgets.alerts_admin');


        $overwrite = false;
        if ( ! empty($id)) {
            $overwrite = true;
        }

        try {
            $obj = $this->alerts_model->savealert($data, $overwrite, $is_admin);
        } catch (Exception $e) {
            respond_internal_error($e->getMessage());
        }

        if ( ! $obj) //not able to get inserted alert
        {
            $errors = $this->alerts_model->getErrors();
            $data   = json_encode($errors);
            respond_internal_error($data);

            return;
        } else {
            $data    = array();
            $data[0] = array('alertId'   => $obj->id,
                             'text'      => $this->lang->line('dashboard_alert_save_success'),
                             'errorCode' => 200
            );
            respond_ok(json_encode($data));

            return;
        }
    }

    function deletealert_delete($id)
    {

        $username = $this->session->userdata('username');
        $is_admin = isActionAllowed('widgets.alerts_admin');

        try {
            $result = $this->alerts_model->deletealert($id, $username, $is_admin);
            $json   = json_encode($result);
            respond_ok($json);
        } catch (Exception $e) {
            $message = $e->getMessage();
            log_message('debug', 'Unable to delete alert. Error: ' . $message);
            respond_internal_error($message);
        }
    }

    /**
     * Return list of alert hosts
     *
     * @param <string> $id - alertId
     */
    function getalerthosts_post($id)
    {
        $username = $this->session->userdata('username');
        $is_admin = isActionAllowed('widgets.alerts_admin');

        $data       = json_decode($this->request->body, true);
        $load_limit = $data['load_limit'];

        try {
            $result = $this->alerts_model->getalerthosts($id, $username, $is_admin, $load_limit);
            $json   = json_encode($result);
            respond_ok($json);
        } catch (Exception $e) {
            $message = $e->getMessage();
            log_message('debug', 'Unable to delete alert. Error: ' . $message);
            respond_internal_error($message);
        }
    }


    function pausealert_post()
    {
        $data = json_decode($this->request->body, true);


        $dataToSave = array();

        $dataToSave['paused'] = 1;
        $dataToSave['pause']  = ((int)$data['time']) !== -1 ? $data['time'] + time() : -1;

        $alertId = $data['alertid'];


        $username = $this->session->userdata('username');

        $is_admin = isActionAllowed('widgets.alerts_admin');

        if ( ! isset($data['alertid'])) {
            $message = 'Unable to pause alert: Alert id is empty';
            log_message('debug', $message);
            respond_internal_error($message);

            return;
        }

        try {
            $filter['id'] = intval($alertId);

            if ($is_admin === false) {
                $filter['username'] = $username;
            }

            $this->alerts_model->updateAlert($filter, $dataToSave);
        } catch (Exception $e) {
            $message = $e->getMessage();
            log_message('debug', 'Unable to pause alert: ' . $message);
            respond_internal_error($message);

            return;
        }

        $result    = array();
        $result[0] = array('text' => $this->lang->line('dashboard_alert_paused_success'), 'errorCode' => 200);
        respond_ok(json_encode($result));

        return;
    }

    function resumealert_post()
    {
        $data = json_decode($this->request->body, true);


        $dataToSave = array();

        $dataToSave['paused'] = 0;
        $dataToSave['pause']  = 0;

        $alertId = $data['alertid'];


        $username = $this->session->userdata('username');

        $is_admin = isActionAllowed('widgets.alerts_admin');

        if ( ! isset($data['alertid'])) {
            $message = $e->getMessage();
            log_message('debug', 'Unable to resume alert: Alert id is empty');
            respond_internal_error($message);

            return;
        }

        try {
            $filter['id'] = (int)$alertId;

            if ($is_admin === false) {
                $filter['username'] = $username;
            }

            $this->alerts_model->updateAlert($filter, $dataToSave);
        } catch (Exception $e) {
            $message = $e->getMessage();
            log_message('debug', 'Unable to resume alert: ' . $message);
            respond_internal_error($message);

            return;
        }

        $result    = array();
        $result[0] = array('text' => $this->lang->line('dashboard_alert_resumed_success'), 'errorCode' => 200);
        respond_ok(json_encode($result));

        return;
    }

    /**
     * Return statistical information for group of alerts by severity
     * result array like
     *  ['high']   = array('failAlerts' => 0, 'totalAlerts' => 0, 'failHosts' => 0, 'totalHosts' => 0);
     * ['medium'] = array('failAlerts' => 0, 'totalAlerts' => 0, 'failHosts' => 0, 'totalHosts' => 0);
     * ['low']    = array('failAlerts' => 0, 'totalAlerts' => 0, 'failHosts' => 0, 'totalHosts' => 0);
     *
     *
     * @return type
     */
    function getalertstatsbyseverity_post()
    {
        $data     = json_decode($this->request->body, true);
        $username = $this->session->userdata('username');
        $cacheKey = $username . implode('_', $data['alertsIds']);

        if ($this->cache->get($cacheKey)) {
            respond_ok($this->cache->get($cacheKey));

            return true;
        }

        if (empty($data['alertsIds'])) {
            $message = $this->lang->line('dashboard_alert_list_is_empty');
            log_message('debug', 'Unable get alert info: ' . $message);
            respond_internal_error($message);

            return;
        }

        try {
            $alertsIds = array_unique($data['alertsIds']);
            $alertsIds = array_map('intval', $alertsIds);
            $cacheTTL = $this->config->item('default_cache_ttl');

            $filter = sprintf('((pause != -1 AND pause <= %s) OR pause IS NULL) ', time());

            $alertsList = $this->alerts_model->get_alerts_with_ids($alertsIds, $filter);

            if (empty($alertsList)) {
                $message = $this->lang->line('dashboard_alert_list_is_empty');
                log_message('debug', 'Unable get alert info: ' . $message);
                respond_internal_error($message);

                return;
            }

            $result = $this->alerts_model->getAlertStats($alertsList);
            // Save into the cache for 5 minutes
            $json = json_encode($result);
            $this->cache->save($cacheKey, $json, $cacheTTL);
            respond_ok($json);
        } catch (Exception $e) {
            $message = $e->getMessage();
            log_message('debug', 'Failed retrieving alerts, error: ' . $message);
            respond_internal_error($message);
        }
    }

    /* Utils functions */

    function _getDefaultAlertName_DC($activationName)
    {
        return $activationName;
    }

    function _getDefaultRuleName_DC($activationName)
    {
        return $activationName;
    }

}