<?php

class CachetBridge extends BridgeAbstract
{
    const NAME = 'Cachet Bridge';
    const URI = 'https://cachethq.io/';
    const DESCRIPTION = 'Returns status updates from any Cachet installation';
    const MAINTAINER  = 'klimplant';
    const PARAMETERS = [
        [
            'host' => [
                'name' => 'Cachet installation',
                'type' => 'text',
                'required' => true,
                'title' => 'The URL of the Cachet installation',
                'exampleValue' => 'https://demo.cachethq.io/',
            ], 'additional_info' => [
                'name' => 'Additional Timestamps',
                'type' => 'checkbox',
                'title' => 'Whether to include the given timestamps'
            ]
        ]
    ];
    const CACHE_TIMEOUT = 300;

    private $componentCache = [];

    public function getURI()
    {
        return $this->getInput('host') === null ? 'https://cachethq.io/' : $this->getInput('host');
    }

    /**
     * Validates the ping request to the cache API
     *
     * @param string $ping
     * @return boolean
     */
    private function validatePing($ping)
    {
        $ping = json_decode($ping);
        if ($ping === null) {
            return false;
        }
        return $ping->data === 'Pong!';
    }

    /**
     * Returns the component name of a cachat component
     *
     * @param integer $id
     * @return string
     */
    private function getComponentName($id)
    {
        if ($id === 0) {
            return '';
        }
        if (array_key_exists($id, $this->componentCache)) {
            return $this->componentCache[$id];
        }

        $component = getContents($this->getURI() . '/api/v1/components/' . $id);
        $component = json_decode($component);
        if ($component === null) {
            return '';
        }
        return $component->data->name;
    }

    public function collectData()
    {
        $ping = getContents(urljoin($this->getURI(), '/api/v1/ping'));
        if (!$this->validatePing($ping)) {
            returnClientError('Provided URI is invalid!');
        }

        $url = urljoin($this->getURI(), '/api/v1/incidents?sort=id&order=desc');
        $incidents = getContents($url);
        $incidents = json_decode($incidents);
        if ($incidents === null) {
            returnClientError('/api/v1/incidents returned no valid json');
        }

        usort($incidents->data, function ($a, $b) {
            $timeA = strtotime($a->updated_at);
            $timeB = strtotime($b->updated_at);
            return $timeA > $timeB ? -1 : 1;
        });

        foreach ($incidents->data as $incident) {
            if (isset($incident->permalink)) {
                $permalink = $incident->permalink;
            } else {
                $permalink = urljoin($this->getURI(), '/incident/' . $incident->id);
            }

            $title = $incident->human_status . ': ' . $incident->name;
            $message = '';
            if ($this->getInput('additional_info')) {
                if (isset($incident->occurred_at)) {
                    $message .= 'Occurred at: ' . $incident->occurred_at . "\r\n";
                }
                if (isset($incident->scheduled_at)) {
                    $message .= 'Scheduled at: ' . $incident->scheduled_at . "\r\n";
                }
                if (isset($incident->created_at)) {
                    $message .= 'Created at: ' . $incident->created_at . "\r\n";
                }
                if (isset($incident->updated_at)) {
                    $message .= 'Updated at: ' . $incident->updated_at . "\r\n\r\n";
                }
            }

            $message .= $incident->message;
            $content = nl2br($message);
            $componentName = $this->getComponentName($incident->component_id);
            $uidOrig = $permalink . $incident->created_at;
            $uid = hash('sha512', $uidOrig);
            $timestamp = strtotime($incident->created_at);
            $categories = [];
            $categories[] = $incident->human_status;
            if ($componentName !== '') {
                $categories[] = $componentName;
            }

            $item = [];
            $item['uri'] = $permalink;
            $item['title'] = $title;
            $item['timestamp'] = $timestamp;
            $item['content'] = $content;
            $item['uid'] = $uid;
            $item['categories'] = $categories;

            $this->items[] = $item;
        }
    }
}