<?php

namespace App\Console\Commands\Utility;

use Illuminate\Support\Facades\Notification;
use App\Notifications\SlackNotification;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class SystemHealthCheck extends \App\Console\Commands\BaseCommand
{

    protected $signature = 'utility:system-health-check';

    protected $description = 'Monitors given things to determine whether Creatia is still working.';

    public function handle()
    {
        try {

            $recently_sent_heartbeat = Redis::get('command:utility:system-health-check:heartbeat');

            $things_to_send = [];

            /** File monitoring - Check that files are being written regularly. */

            foreach([
                'prefix.detailed.json'  => '> The `detailed-4` prefix list has not updated in the past half hour.',
                'prefix.detailed6.json'  => '> The `detailed-4` prefix list has not updated in the past half hour.',
            ] as $file => $message) {
                
                if(filemtime(storage_path($file)) < (time() - 1800)) {
                    $things_to_send[] = $message;
                }

            }

            /** Service monitoring - Check that services are up and not hung. */

            foreach([
                'creatia-attack-collection'     => 300,
                'creatia-attack-enrichment'     => 600,
                'creatia-attack-notification'   => 300,
                'creatia-broadcast.timer'       => null,
                'creatia-fast-bgp'              => 90,
                'creatia-fast-dispatch'         => 60,
                'creatia-fast-goliath'          => 60,
                'creatia-fast-sort'             => 60,
                'creatia-goliath-config'        => 60,
                'creatia-map-cache'             => 60,
                'creatia-monitor-attack'        => 60,
                'creatia-reporting-cache-tables'=> 300,
                'creatia-websockets'            => null,
                'goliath-level-1'               => null

            ] as $service => $frozen_time) {
                $status = shell_exec("systemctl status $service");

                if($status === null) continue;

                $is_active = preg_match('/Active: (active|activating)/', $status);

                $timestamp = [];

                preg_match('/\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}\:\d{2}/', $status, $timestamp);

                $is_frozen = $frozen_time === null ? false : time() - Carbon::parse($timestamp[0])->unix() > $frozen_time;

                if($is_frozen || !$is_active) {

                    $minutes = ($frozen_time / 60);

                    $things_to_send[] = $is_active ? "> The `$service` service has exceeded the set threshold." : "> The `$service` service is not active."; 
                
                }

            }

            /** Endpoint monitoring - Check that services are responsive to baseline commands. */

            $message = '';

            if(sizeof($things_to_send)) {
                $message = "*Creatia Monitoring Statement:*\n" . implode("\n", $things_to_send);
            }
            elseif(!$recently_sent_heartbeat) {
                $message = "*Creatia Monitoring Statement:*\n> System Healthy. Sending next heartbeat in six hours, or when the next issue is found.";

                Redis::setex('command:utility:system-health-check:heartbeat', 3600 * 6, true);
            }

            Log::info($message);

            if($message !== '') {
                Notification::route('slack', config('creatia.webhook.appliance'))->notify(new SlackNotification($message));
            }


        }
        catch(\Throwable $e) {}

        return 0;
    }
}