<?php

namespace App\Console\Commands\Report;

use App\Models\Goliath\GoliathAttack;
use App\Models\Goliath\GoliathAttackCollected;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;

class ReportAttackInfo extends \App\Console\Commands\BaseCommand
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'report-attack:info';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Build the singular attack information object.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {

        $attack_records = GoliathAttack::join('goliath_attack_prefixes', 'attack_id', '=', 'goliath_attacks.id')
            ->join('prefixes', 'prefix_id', '=', 'prefixes.id')
            ->leftJoin('goliath_attack_collected', 'goliath_attack_collected.attack_id', '=', 'goliath_attacks.id')
            ->where('started_at', '>', Carbon::now()->subMinutes(360))
            ->whereNull('goliath_attack_collected.attack_id')
            ->select(
                'started_at as mitigate_start_at',
                'last_at as mitigate_finish_at',
                'destination',
                DB::raw('set_masklen(concat(destination, \'/32\')::cidr, 24) as destination_parent'),
                'description as type',
                'goliath_attacks.id as creatia_attack_id',
                'prefixes.organisation_id as creatia_organisation_id',
                'prefixes.name as name'
            )
            ->orderBy('started_at')
            ->distinct()
            ->get();

        foreach(array_chunk($attack_records->toArray(), 500) as $chunk) {
            $to_insert_info = [];
            $to_insert_seen = [];
            $to_insert_describe = [];
            $quick_delete_ids = [];

            foreach($chunk as $row) {
                $v4 = str_contains($row['destination'], '.') ? true : false;

                $to_insert_info[] = [
                    'mitigate_start_at'         => (int)Carbon::parse($row['mitigate_start_at'])->timestamp,
                    'mitigate_finish_at'        => (int)Carbon::parse($row['mitigate_finish_at'])->timestamp,
                    'destination_addr'          => (string)$row['destination'],
                    'destination_addr_type'     => (string)($v4 ? '4' : '6'),
                    'destination_parent'        => (string)explode('/', $row['destination_parent'])[0],
                    'type'                      => (string)$row['type'],
                    'creatia_organisation_id'   => (int)$row['creatia_organisation_id'],
                    'creatia_attack_id'         => (int)$row['creatia_attack_id']
                ];

                $to_insert_seen[] = [
                    'attack_id' => $row['creatia_attack_id']
                ];

                if(isset($row['name']) && $row['name'] !== '') {
                    $to_insert_describe[] = [
                        'creatia_attack_id' => $row['creatia_attack_id'],
                        'descriptor' => $row['name']
                    ];
                }

                $quick_delete_ids[] = $row['creatia_attack_id'];
            }

            if($to_insert_info !== [] && $to_insert_seen !== []) {

                $this->log_event("Attempting to insertion attacks.", [
                    'count' => sizeof($to_insert_info),
                    'identities' => $to_insert_seen
                ]);

                try {

                    GoliathAttackCollected::insert($to_insert_seen);

                    Http::timeout(3600)->withBasicAuth('creatia', config('creatia.reporting.microservice_password'))->withHeaders(['Content-Type' => 'application/json'])->post(config('creatia.reporting.microservice_url') . '/creatia-report/attack', [ 
                        'attacks' => $to_insert_info
                    ]);

                    Http::timeout(3600)->withBasicAuth('creatia', config('creatia.reporting.microservice_password'))->withHeaders(['Content-Type' => 'application/json'])->post(config('creatia.reporting.microservice_url') . '/creatia-report/descriptor', [ 
                        'attacks' => $to_insert_describe
                    ]);

                }
                catch(\Exception $ex) {

                    $this->log_error("Failure in inserting attacks.", [
                        'identities' => $quick_delete_ids,
                        'exception' => $ex
                    ]);

                    GoliathAttackCollected::whereIn('attack_id', $quick_delete_ids)->delete();

                }
    
            }
        }

        return 0;
    }
}