<?php

function fusioncore_poll_servicestatus(&$raw_data) {
    
    $data = array(
        'services_pending'         => 0,
        'services_ok'              => 0,
        'services_warning'         => 0,
        'services_critical'        => 0,
        'services_unknown'         => 0,
        );

    $meta = array(

        'services_problems'                 => 0,
        'services_problems_unhandled'       => 0,

        'services_disabled'                 => 0,
        'services_acknowledged'             => 0,
        'services_flapping'                 => 0,
        'services_downtime'                 => 0,

        'services_pending_disabled'         => 0,

        'services_ok_disabled'              => 0,
        'services_ok_downtime'              => 0,

        'services_warning_disabled'         => 0,
        'services_warning_acknowledged'     => 0,
        'services_warning_downtime'         => 0,

        'services_critical_disabled'        => 0,
        'services_critical_acknowledged'    => 0,
        'services_critical_downtime'        => 0,

        'services_unknown_disabled'         => 0,
        'services_unknown_acknowledged'     => 0,
        'services_unknown_downtime'         => 0,

        );

    $servicestatuslist = array();

    $xi = false;
    $core = false;

    // xi
    if (!empty($raw_data['servicestatuslist']['servicestatus'])) {

        $xi = true;
        $servicestatuslist = $raw_data['servicestatuslist']['servicestatus'];

        if ($raw_data['servicestatuslist']['recordcount'] == 1)
            $servicestatuslist = array($servicestatuslist);
    }

    // core
    if (!empty($raw_data['data']['servicelist'])) {

        $core = true;
        $servicestatuslist = $raw_data['data']['servicelist'];
    }

    // have to let the poller know we're not the one..
    if (!$xi && !$core)
        return null;

    // array to save
    $service_status = array();

    if ($xi) {
        foreach ($servicestatuslist as $index => $service) {

            // grab the meta data
            $disabled = false;
            $downtime = false;
            $acknowledged = false;

            // checks disabled?
            if (   (isset($service['active_checks_enabled']) && $service['active_checks_enabled'] == 0)
                    && (isset($service['passive_checks_enabled']) && $service['passive_checks_enabled'] == 0)) {

                $disabled = true;
                $meta['services_disabled']++;
            }

            // acknowledged?
            if (!empty($service['problem_acknowledged'])) {

                $acknowledged = true;
                $meta['services_acknowledged']++;
            }

            // downtime?
            if (!empty($service['scheduled_downtime_depth'])) {

                $downtime = true;
                $meta['services_downtime']++;
            }

            // flapping?
            if (!empty($service['is_flapping']))
                $meta['services_flapping']++;

            $current_state = STATE_UNKNOWN;
            if (isset($service['current_state']))
                $current_state = $service['current_state'];

            // build the service_status array
            if (!empty($service['host_name']) && !empty($service['name'])) {
                $host = $service['host_name'];
                $svc_desc = $service['name'];

                $display_name = '';
                if (!empty($service['display_name']))
                    $display_name = $service['display_name'];

                $output = '';
                if (isset($service['status_text']))
                    $output = $service['status_text'];

                $service_status[$host][$svc_desc] = array(
                    'display_name'      => $display_name,
                    'current_state'     => $current_state,
                    'output'            => $output,
                    'disabled'          => intval($disabled),
                    'downtime'          => intval($downtime),
                    'acknowledged'      => intval($acknowledged),
                    );
            }

            switch ($current_state) {
                case STATE_OK:

                    if (isset($service['has_been_checked']) && $service['has_been_checked'] == 0) {

                        $data['services_pending']++;

                        if ($disabled)
                            $meta['services_pending_disabled']++;

                    } else {

                        $data['services_ok']++;

                        if ($disabled)
                            $meta['services_ok_disabled']++;

                        if ($downtime)
                            $meta['services_ok_downtime']++;                        
                    }
                    break;

                case STATE_WARNING:

                    $data['services_warning']++;

                    $meta['services_problems']++;
                    $meta['services_problems_unhandled']++;

                    if ($disabled)
                        $meta['services_warning_disabled']++;

                    if ($acknowledged)
                        $meta['services_warning_acknowledged']++;

                    if ($downtime)
                        $meta['services_warning_downtime']++;

                    if ($downtime || $acknowledged)
                        $meta['services_problems_unhandled']--;
                    
                    break;

                case STATE_CRITICAL:

                    $data['services_critical']++;

                    $meta['services_problems']++;
                    $meta['services_problems_unhandled']++;

                    if ($disabled)
                        $meta['services_critical_disabled']++;

                    if ($acknowledged)
                        $meta['services_critical_acknowledged']++;

                    if ($downtime)
                        $meta['services_critical_downtime']++;

                    if ($downtime || $acknowledged)
                        $meta['services_problems_unhandled']--;
                    
                    break;

                case STATE_UNKNOWN:

                    $data['services_unknown']++;
                    
                    $meta['services_problems']++;
                    $meta['services_problems_unhandled']++;

                    if ($disabled)
                        $meta['services_unknown_disabled']++;

                    if ($acknowledged)
                        $meta['services_unknown_acknowledged']++;

                    if ($downtime)
                        $meta['services_unknown_downtime']++;

                    if ($downtime || $acknowledged)
                        $meta['services_problems_unhandled']--;

                    break;
            }
        }
    }

    if ($core) {
        foreach ($servicestatuslist as $host => $services) {
            foreach ($services as $svc_desc => $service) {

                // grab the meta data
                $disabled = false;
                $downtime = false;
                $acknowledged = false;

                // checks disabled?
                if (    (isset($service['accept_passive_checks']) && empty($service['accept_passive_checks']))
                     && (isset($service['checks_enabled']) && empty($service['checks_enabled']))) {

                    $disabled = true;
                    $meta['services_disabled']++;
                 }

                // acknowledged?
                if (!empty($service['problem_has_been_acknowledged'])) {

                    $acknowledged = true;
                    $meta['services_acknowledged']++;
                }

                // downtime?
                if (!empty($service['scheduled_downtime_depth'])) {

                    $downtime = true;
                    $meta['services_downtime']++;
                }

                // flapping?
                if (!empty($service['is_flapping']))
                    $meta['services_flapping']++;

                $status = CORE_SERVICE_UNKNOWN;
                if (isset($service['status']))
                    $status = $service['status'];

                // build the service_status array
                $current_state = STATE_UNKNOWN;
                switch ($status) {
                    case CORE_SERVICE_PENDING:      $current_state = STATE_OK; break;
                    case CORE_SERVICE_OK:           $current_state = STATE_OK; break;
                    case CORE_SERVICE_WARNING:      $current_state = STATE_WARNING; break;
                    case CORE_SERVICE_CRITICAL:     $current_state = STATE_CRITICAL; break;
                    case CORE_SERVICE_UNKNOWN:      $current_state = STATE_UNKNOWN; break;
                }

                $output = '';
                if (isset($service['plugin_output']))
                    $output = $service['plugin_output'];

                $service_status[$host][$svc_desc] = array(
                    'display_name'      => $svc_desc,
                    'current_state'     => $current_state,
                    'output'            => $output,
                    'disabled'          => intval($disabled),
                    'downtime'          => intval($downtime),
                    'acknowledged'      => intval($acknowledged),
                    );

                switch($status) {

                    case CORE_SERVICE_PENDING:

                        $data['services_pending']++;

                        if ($disabled)
                            $meta['services_pending_disabled']++;

                        break;

                    case CORE_SERVICE_OK:

                        $data['services_ok']++;

                        if ($disabled)
                            $meta['services_ok_disabled']++;

                        if ($downtime)
                            $meta['services_ok_downtime']++;

                        break;

                    case CORE_SERVICE_WARNING:

                        $data['services_warning']++;

                        $meta['services_problems']++;
                        $meta['services_problems_unhandled']++;

                        if ($disabled)
                            $meta['services_warning_disabled']++;

                        if ($acknowledged)
                            $meta['services_warning_acknowledged']++;

                        if ($downtime)
                            $meta['services_warning_downtime']++;

                        if ($downtime || $acknowledged)
                            $meta['services_problems_unhandled']--;

                        break;

                    case CORE_SERVICE_CRITICAL:

                        $data['services_critical']++;
                        
                        $meta['services_problems']++;
                        $meta['services_problems_unhandled']++;

                        if ($disabled)
                            $meta['services_critical_disabled']++;

                        if ($acknowledged)
                            $meta['services_critical_acknowledged']++;

                        if ($downtime)
                            $meta['services_critical_downtime']++;

                        if ($downtime || $acknowledged)
                            $meta['services_problems_unhandled']--;

                        break;

                    case CORE_SERVICE_UNKNOWN:

                        $data['services_unknown']++;
                        
                        $meta['services_problems']++;
                        $meta['services_problems_unhandled']++;

                        if ($disabled)
                            $meta['services_unknown_disabled']++;

                        if ($acknowledged)
                            $meta['services_unknown_acknowledged']++;

                        if ($downtime)
                            $meta['services_unknown_downtime']++;

                        if ($downtime || $acknowledged)
                            $meta['services_problems_unhandled']--;

                        break;
                }
            }
        }
    }

    $data['services_count'] = array_sum($data);
    $data['service_status'] = $service_status;

    return array_merge($data, $meta);
}
