notificationData = $this->createNotificationData();
        $this->problemData = $this->createProblemData();
    }
    /**
     * Create full report
     */
    public function indexAction()
    {
        $this->getTabs()->add(
            'alertsummary',
            array(
                'title' => $this->translate(
                    'Show recent alerts and visualize notifications and problems'
                    . ' based on their amount and chronological distribution'
                ),
                'label' => $this->translate('Alert Summary'),
                'url'   => Url::fromRequest()
            )
        )->activate('alertsummary');
        $this->view->title = $this->translate('Alert Summary');
        $this->view->intervalBox = $this->createIntervalBox();
        $this->view->recentAlerts = $this->createRecentAlerts();
        $this->view->interval = $this->getInterval();
        $this->view->defectChart = $this->createDefectImage();
        $this->view->healingChart = $this->createHealingChart();
        $this->view->perf = $this->createNotificationPerfdata();
        $this->view->trend = $this->createTrendInformation();
        $this->setAutorefreshInterval(15);
        $query = $this->backend->select()->from(
            'notification',
            array(
                'host',
                'host_display_name',
                'service',
                'service_display_name',
                'notification_output',
                'notification_contact',
                'notification_start_time',
                'notification_state'
            )
        );
        $this->view->notifications = $query->paginate();
    }
    /**
     * Create data for charts
     *
     * @return array
     */
    private function createNotificationData()
    {
        $interval = $this->getInterval();
        $query = $this->backend->select()->from(
            'notification',
            array(
                'host',
                'service',
                'notification_output',
                'notification_contact',
                'notification_start_time',
                'notification_state'
            )
        );
        $query->setFilter(
            new Icinga\Data\Filter\FilterExpression(
                'n.start_time',
                '>=',
                $this->getBeginDate($interval)->format('Y-m-d H:i:s')
            )
        );
        $query->order('notification_start_time', 'asc');
        $records    = $query->getQuery()->fetchAll();
        $data       = array();
        $period     = $this->createPeriod($interval);
        foreach ($period as $entry) {
            $id = $this->getPeriodFormat($interval, $entry->getTimestamp());
            $data[$id] = array($id, 0);
        }
        foreach ($records as $item) {
            $id = $this->getPeriodFormat($interval, $item->notification_start_time);
            if (empty($data[$id])) {
                $data[$id] = array($id, 0);
            }
            $data[$id][1]++;
        }
        return $data;
    }
    /**
     * Trend information for notifications
     *
     * @return stdClass
     */
    private function createTrendInformation()
    {
        $date = new DateTime();
        $beginDate = $date->sub(new DateInterval('P3D'));
        $query = $this->backend->select()->from(
            'notification',
            array(
                'host',
                'service',
                'notification_output',
                'notification_contact',
                'notification_start_time',
                'notification_state'
            )
        );
        $query->setFilter(
            new Icinga\Data\Filter\FilterExpression(
                'n.start_time',
                '>=',
                $beginDate->format('Y-m-d H:i:s')
            )
        );
        $query->order('notification_start_time', 'asc');
        $records = $query->getQuery()->fetchAll();
        $slots = array();
        $period = new DatePeriod($beginDate, new DateInterval('P1D'), 2, DatePeriod::EXCLUDE_START_DATE);
        foreach ($period as $entry) {
            $slots[$entry->format('Y-m-d')] = 0;
        }
        foreach ($records as $item) {
            $id = strftime('%Y-%m-%d', $item->notification_start_time);
            if (isset($slots[$id])) {
                $slots[$id]++;
            }
        }
        $yesterday = array_shift($slots);
        $today = array_shift($slots);
        $out = new stdClass();
        if ($yesterday === $today) {
            $out->trend = $this->translate('unchanged');
        } elseif ($yesterday > $today) {
            $out->trend = $this->translate('down');
        } else {
            $out->trend = $this->translate('up');
        }
        if ($yesterday <= 0) {
            $out->percent = 100;
        } elseif ($yesterday === $today) {
            $out->percent = 0;
        } else {
            $out->percent = sprintf(
                '%.2f',
                100 - ((100/($yesterday > $today ? $yesterday : $today)) * ($yesterday > $today ? $today : $yesterday))
            );
        }
        return $out;
    }
    /**
     * Perfdata for notifications
     *
     * @return stdClass
     */
    private function createNotificationPerfdata()
    {
        $interval = $this->getInterval();
        $query = $this->backend->select()->from(
            'notification',
            array(
                'notification_start_time'
            )
        );
        $query->setFilter(
            new Icinga\Data\Filter\FilterExpression(
                'n.start_time',
                '>=',
                $this->getBeginDate($interval)->format('Y-m-d H:i:s')
            )
        );
        $query->order('notification_start_time', 'desc');
        $records = $query->getQuery()->fetchAll();
        $slots = array();
        foreach ($records as $item) {
            $id = strftime('%Y-%m-%d %H:%I:00', $item->notification_start_time);
            if (empty($slots[$id])) {
                $slots[$id] = 0;
            }
            $slots[$id]++;
        }
        $out = new stdClass();
        if (! empty($slots)) {
            $out->avg = sprintf('%.2f', array_sum($slots) / count($slots));
        } else {
            $out->avg = '0.0';
        }
        $out->last = array_shift($slots);
        return $out;
    }
    /**
     * Problems for notifications
     *
     * @return array
     */
    private function createProblemData()
    {
        $interval = $this->getInterval();
        $query = $this->backend->select()->from(
            'eventHistory',
            array(
                'timestamp'
            )
        );
        $query->addFilter(
            new Icinga\Data\Filter\FilterExpression(
                'timestamp',
                '>=',
                $this->getBeginDate($interval)->getTimestamp()
            )
        );
        $query->addFilter(
            new Icinga\Data\Filter\FilterExpression(
                'state',
                '>',
                0
            )
        );
        $defects = array();
        $records = $query->getQuery()->fetchAll();
        $period     = $this->createPeriod($interval);
        foreach ($period as $entry) {
            $id = $this->getPeriodFormat($interval, $entry->getTimestamp());
            $defects[$id] = array($id, 0);
        }
        foreach ($records as $item) {
            $id = $this->getPeriodFormat($interval, $item->timestamp);
            if (empty($defects[$id])) {
                $defects[$id] = array($id, 0);
            }
            $defects[$id][1]++;
        }
        return $defects;
    }
    /**
     * Healing svg image
     *
     * @return GridChart
     */
    public function createHealingChart()
    {
        $gridChart = new GridChart();
        $gridChart->title = $this->translate('Healing Chart');
        $gridChart->description = $this->translate('Notifications and average reaction time per hour.');
        $gridChart->alignTopLeft();
        $gridChart->setAxisLabel($this->createPeriodDescription(), $this->translate('Notifications'))
            ->setXAxis(new StaticAxis())
            ->setYAxis(new LinearUnit(10))
            ->setAxisMin(null, 0);
        $interval = $this->getInterval();
        $query = $this->backend->select()->from(
            'notification',
            array(
                'host',
                'service',
                'notification_object_id',
                'notification_output',
                'notification_contact',
                'notification_start_time',
                'notification_state',
                'acknowledgement_entry_time'
            )
        );
        $query->setFilter(
            new Icinga\Data\Filter\FilterExpression(
                'n.start_time',
                '>=',
                $this->getBeginDate($interval)->format('Y-m-d H:i:s')
            )
        );
        $query->order('notification_start_time', 'asc');
        $records = $query->getQuery()->fetchAll();
        $interval       = $this->getInterval();
        $period         = $this->createPeriod($interval);
        $dAvg           = array();
        $dMax           = array();
        $notifications  = array();
        $rData          = array();
        foreach ($period as $entry) {
            $id = $this->getPeriodFormat($interval, $entry->getTimestamp());
            $dMax[$id] = array($id, 0);
            $dAvg[$id] = array($id, 0, 0);
            $notifications[$id] = array($id, 0);
        }
        foreach ($records as $item) {
            $id = $this->getPeriodFormat($interval, $item->notification_start_time);
            if ($item->notification_state == '0' && isset($rData[$item->notification_object_id])) {
                $rData[$item->notification_object_id]['recover'] =
                    $item->notification_start_time - $rData[$item->notification_object_id]['entry'];
            } elseif ($item->notification_state !== '0') {
                $recover = 0;
                if ($item->acknowledgement_entry_time) {
                    $recover = $item->acknowledgement_entry_time - $item->notification_start_time;
                    /*
                     * Acknowledgements may happen before the actual notification starts, since notifications
                     * can be configured to start a certain time after the problem. In that case we assume
                     * a reaction time of 0s.
                     */
                    if ($recover < 0) {
                        $recover = 0;
                    }
                }
                $rData[$item->notification_object_id] = array(
                    'id'        => $id,
                    'entry'     => $item->notification_start_time,
                    'recover'   => $recover
                );
            }
        }
        foreach ($rData as $item) {
            $notifications[$item['id']][1]++;
            if ($item['recover'] > $dMax[$item['id']][1]) {
                $dMax[$item['id']][1] = (int) $item['recover'];
            }
            $dAvg[$item['id']][1] += (int) $item['recover'];
            $dAvg[$item['id']][2]++;
        }
        foreach ($dAvg as &$item) {
            if ($item[2] > 0) {
                $item[1] = ($item[1]/$item[2])/60/60;
            }
        }
        foreach ($dMax as &$item) {
            $item[1] = $item[1]/60/60;
        }
        $gridChart->drawBars(
            array(
                'label' => $this->translate('Notifications'),
                'color' => '#07C0D9',
                'data'  =>  $notifications,
                'showPoints' => true,
                'tooltip' => '{title}: {value} {label}'
            )
        );
        $gridChart->drawLines(
            array(
                'label' => $this->translate('Avg (min)'),
                'color' => '#ffaa44',
                'data'  =>  $dAvg,
                'showPoints' => true,
                'tooltip' => $this->translate('{title}: {value}m min. reaction time')
            )
        );
        $gridChart->drawLines(
            array(
                'label' => $this->translate('Max (min)'),
                'color' => '#ff5566',
                'data'  =>  $dMax,
                'showPoints' => true,
                'tooltip' => $this->translate('{title}: {value}m max. reaction time')
            )
        );
        return $gridChart;
    }
    /**
     * Notifications and defects
     *
     * @return GridChart
     */
    public function createDefectImage()
    {
        $gridChart = new GridChart();
        $gridChart->title = $this->translate('Defect Chart');
        $gridChart->description = $this->translate('Notifications and defects per hour');
        $gridChart->alignTopLeft();
        $gridChart->setAxisLabel($this->createPeriodDescription(), $this->translate('Notifications'))
            ->setXAxis(new StaticAxis())
            ->setYAxis(new LinearUnit(10))
            ->setAxisMin(null, 0);
        $gridChart->drawBars(
            array(
                'label' => $this->translate('Notifications'),
                'color' => '#07C0D9',
                'data'  =>  $this->notificationData,
                'showPoints' => true,
                'tooltip' => '{title}: {value} {label}'
            )
        );
        $gridChart->drawLines(
            array(
                'label' => $this->translate('Defects'),
                'color' => '#ff5566',
                'data'  =>  $this->problemData,
                'showPoints' => true,
                'tooltip' => '{title}: {value} {label}'
            )
        );
        return $gridChart;
    }
    /**
     * Top recent alerts
     *
     * @return mixed
     */
    private function createRecentAlerts()
    {
        $query = $this->backend->select()->from(
            'notification',
            array(
                'host',
                'host_display_name',
                'service',
                'service_display_name',
                'notification_output',
                'notification_contact',
                'notification_start_time',
                'notification_state'
            )
        );
        $query->order('notification_start_time', 'desc');
        return $query->paginate(5);
    }
    /**
     * Interval selector box
     *
     * @return SelectBox
     */
    private function createIntervalBox()
    {
        $box = new SelectBox(
            'intervalBox',
            array(
                '1d' => $this->translate('One day'),
                '1w' => $this->translate('One week'),
                '1m' => $this->translate('One month'),
                '1y' => $this->translate('One year')
            ),
            $this->translate('Report interval'),
            'interval'
        );
        $box->applyRequest($this->getRequest());
        return $box;
    }
    /**
     * Return reasonable date time format for an interval
     *
     * @param   string $interval
     * @param   string $timestamp
     *
     * @return  string
     */
    private function getPeriodFormat($interval, $timestamp)
    {
        $format = '';
        if ($interval === '1d') {
            $format = '%H:00';
        } elseif ($interval === '1w') {
            $format = '%Y-%m-%d';
        } elseif ($interval === '1m') {
            $format = '%Y-%m-%d';
        } elseif ($interval === '1y') {
            $format = '%Y-%m';
        }
        return strftime($format, $timestamp);
    }
    /**
     * Create a reasonable period based in interval strings
     *
     * @param $interval
     * @return DatePeriod
     */
    private function createPeriod($interval)
    {
        if ($interval === '1d') {
            return new DatePeriod($this->getBeginDate($interval), new DateInterval('PT1H'), 24);
        } elseif ($interval === '1w') {
            return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1D'), 7);
        } elseif ($interval === '1m') {
            return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1D'), 31);
        } elseif ($interval === '1y') {
            return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1M'), 12);
        }
    }
    /**
     * Return start timestamps based on interval strings
     *
     * @param $interval
     * @return DateTime|null
     */
    private function getBeginDate($interval)
    {
        $new = new DateTime();
        if ($interval === '1d') {
            return $new->sub(new DateInterval('P1D'));
        } elseif ($interval === '1w') {
            return $new->sub(new DateInterval('P1W'));
        } elseif ($interval === '1m') {
            return $new->sub(new DateInterval('P1M'));
        } elseif ($interval === '1y') {
            return $new->sub(new DateInterval('P1Y'));
        }
        return null;
    }
    /**
     * Getter for interval
     *
     * @return string
     *
     * @throws Zend_Controller_Action_Exception
     */
    private function getInterval()
    {
        $interval = $this->getParam('interval', '1d');
        if (false === in_array($interval, array('1d', '1w', '1m', '1y'))) {
            throw new Zend_Controller_Action_Exception($this->translate('Value for interval not valid'));
        }
        return $interval;
    }
    /**
     * Create a human-readable description of the current interval size
     *
     * @return string   The description of the current interval size
     */
    private function createPeriodDescription()
    {
        $int = $this->getInterval();
        switch ($int) {
            case '1d':
                return $this->translate('Hour');
                break;
            case '1w';
                return $this->translate('Day');
                break;
            case '1m':
                return $this->translate('Day');
                break;
            case '1y':
                return $this->translate('Month');
                break;
        }
    }
}