<?php

namespace App\Modules\Network\Commands;

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

use App\Modules\Network\Models\Prefixes;

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

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Associate known prefixes against known and approved ASNs, while associating communities and paths.';

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

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

        $announced_prefixes = [];

        foreach(collect(Http::get("http://54.215.89.235/all.active.detailed.json")->json()) as $announced_prefix) {
            // Split this into sizes so we're always looking at size groups...
            $size = explode('/', $announced_prefix['prefix'])[1];
            if(isset($announced_prefixes[$size])) {
                $announced_prefixes[$size][] = $announced_prefix['prefix'];
            }
            else {
                $announced_prefixes[$size] = [ $announced_prefix['prefix'] ];
            }
        }

        $announced_prefix_ids = [];
        $count = 0;

        foreach($announced_prefixes as $size => $prefixes_full) {
            
            $announced_prefix_ids[$size] = [];

            foreach(array_chunk($prefixes_full, 500) as $prefixes) {
                $prefixes_at_size = Prefixes::where('mask', '=', $size)->whereIn(DB::raw('concat("address", \'/\', "mask")'), $prefixes)->select()->get()->pluck('id')->toArray();

                $announced_prefix_ids[$size] = array_merge($announced_prefix_ids[$size], $prefixes_at_size);

                $count += sizeof($prefixes_at_size);
            }
            
        }

        foreach($announced_prefix_ids as $size => $ids) {
            
            DB::transaction(function() use($ids, $size) {
                // Deannounce
                Prefixes::where('mask', '=', $size)->whereNotIn('id', $ids)->where('created_source', '=', 'prefix-list-uncrushed')->update([
                    'still_announced' => 0
                ]);
    
                // Announce
                Prefixes::where('mask', '=', $size)->whereIn('id', $ids)->where('created_source', '=', 'prefix-list-uncrushed')->update([
                    'seen_at' => Carbon::now(),
                    'still_announced' => 1
                ]);
            });
        
        }
        
        return 0;
    }
}
