<?php

namespace App\Console\Commands\Report;

use App\Models\Goliath\ReportAwareness;
use Carbon\Carbon;
use Illuminate\Support\Facades\Redis;

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

    protected $signature = 'attack-track:completion';

    protected $description = 'Thread to allow selection of all reports and determine whether or not they are concluded...';

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

    public function handle()
    {
        // Load the cached list for automation of singular reports and then group it by subtenant identities.
        $cached_list = Redis::get('report-singular-automation-list');

        if(!$cached_list) {
            return 0;
        }

        $decoded_list = json_decode($cached_list, true)['data'];

        if(!sizeof($decoded_list)) {
            return 0;
        }

        $grouped_organisation_attacks = collect($decoded_list)->flatMap(function ($attack) {
            return collect($attack['subtenants'])->map(function ($subtenant_id) use ($attack) {
                return array_merge($attack, ['subtenant_id' => $subtenant_id]);
            });
        })
        ->groupBy('subtenant_id')
        ->map(function ($attacks) {
            return $attacks->unique('report_id');
        });

        $to_insert = [];

        $now = Carbon::now();

        foreach($grouped_organisation_attacks as $organisation => $completed_attacks) {
            
            // We also need to take a precaution whereby we do NOT reinsert awareness if we already have it - I don't know how this could happen but lets be defensive...
            $finish_aware_of = ReportAwareness::where([['type', '=', 'finish'],['organisation_id', '=', $organisation]])->whereIn('report_id', $completed_attacks->pluck('report_id'))->get()->keyBy('report_id');
            $start_aware_of = ReportAwareness::where([['type', '=', 'start'],['organisation_id', '=', $organisation]])->whereIn('report_id', $completed_attacks->pluck('report_id'))->get()->keyBy('report_id');
            $now_aware_of = [];

            foreach($completed_attacks as $x) {

                // If we've started tracking this now.
                if(isset($now_aware_of[$x['report_id']])) continue;

                // If we're already aware of the report in a finish context, ignore.
                if(isset($finish_aware_of[$x['report_id']])) continue;

                // If we haven't yet tracked a starting event.
                if(!isset($start_aware_of[$x['report_id']])) continue;

                // If it's not completed AND it's still not completed as of the last thirty minutes...
                if(!$x['completed'] && Carbon::parse($x['finish_at'])->diffInMinutes(Carbon::now()) < 30) continue;

                if(round($x['gbps'], 2) == 0 || round($x['mpps'], 2) == 0) continue;

                $now_aware_of[$x['report_id']] = true;

                $to_insert[] = [
                    'created_at'        => $now,
                    'updated_at'        => $now,
                    'type'              => 'finish',
                    'status'            => 'pending',
                    'detected_at'       => Carbon::parse($x['finish_at']),
                    'report_id'         => $x['report_id'],
                    'organisation_id'   => $organisation,
                    'gbps'              => $x['gbps'],
                    'mpps'              => $x['mpps'],
                    'address'           => ltrim($x['destination'], '::ffff:')
                ];

            }
        }

        if($to_insert !== []) {
            ReportAwareness::insert($to_insert);
        }

        return 0;
    }
}