<?php

namespace App\Modules\Network\Commands;

use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Log;

use App\Modules\Network\Models\Supernets;
use App\Modules\Network\Models\Prefixes;
use App\Modules\Network\Models\PrefixExclusions;

use App\Models\Asns;

class PrefixDelete extends \App\Console\Commands\BaseCommand
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'prefix:delete';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Deletes prefixes that have not been recently seen, and their assocations.';

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

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        // Work out addresses that should be excluded from the cleanup process
        $exclusion_cidrs = PrefixExclusions::select(DB::raw("CONCAT(address,'/',mask) as cidr"))->get()->pluck('cidr');
        $exclusion_ids = Prefixes::whereIn(DB::raw("CONCAT(address,'/',mask) as cidr"), $exclusion_cidrs)->get()->pluck('id');

        // Work out what could be deleted - Only select largest supernets, ergo those with no supernets above them.
        $removable_ids = Prefixes::leftJoin('supernets', 'subnet_id', '=', 'prefixes.id')
            ->select(DB::raw('count(*)'),'prefixes.id')
            ->whereNotIn('id', $exclusion_ids)
            ->where('seen_at', '<', Carbon::now()->subDays(30))->groupBy('prefixes.id')
            ->having(DB::raw('count(*)'), '=', '1')
            ->pluck('id');

        // Soft delete our prefixes.
        Prefixes::whereIn('id', $removable_ids)->delete();

        // Hard delete assocations.
        Supernets::whereIn('supernet_id', $removable_ids)->delete();

        return 0;
    }
}