<?php

namespace App\Modules\Network\Commands;

use Log;

use Illuminate\Support\Facades\DB;

use App\Modules\Network\Models\Prefixes;
use App\Modules\Network\Models\GeoIp\PrefixGeoIp;

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

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Sets up geolocation objects.';

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

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        try {
            Prefixes::leftJoin('prefix_geo_ip', 'prefix_id', '=', 'prefixes.id')
                ->select('prefixes.id as relevant_id', 'prefixes.organisation_id', DB::raw('prefix_geo_ip.id as geo_id'))
                ->where(function($x) {
                    $x->whereNull('prefix_id')->whereNull('prefix_geo_ip.deleted_at');
                })
                ->orWhere(function($x) {
                    $x->where('setup_required', '=', 1);
                })
                ->chunk(env('CHUNK_SIZE'), function($prefix_chunk) {
                    
                    $insert_count = $update_count = 0;

                    $to_insert = [];
                    $to_update = [];

                    foreach($prefix_chunk as $prefix) {
                        // Track and delete all old entries for anything requiring setup.
                        if($prefix->geo_id == null) {
                            ++$insert_count;
                            $to_insert[] = [
                                'prefix_id'         => $prefix->relevant_id,
                                'country'           => null,
                                'region'            => null,
                                'city'              => null,
                                'organisation_id'   => $prefix->organisation_id,
                                'whois_error'       => null
                            ];
                        }
                        else {
                            ++$update_count;
                            if(isset($to_update["$prefix->organisation_id"])) {
                                $to_update["$prefix->organisation_id"] = [$prefix->relevant_id];
                            }
                            else {
                                $to_update["$prefix->organisation_id"][] = $prefix->relevant_id;
                            }
                        }
                    }

                    foreach($to_update as $organisation_id => $update) {
                        PrefixGeoIp::whereIn('prefix_id', $update)->update([
                            'country'           => null,
                            'region'            => null,
                            'city'              => null,
                            'organisation_id'   => $organisation_id,
                            'whois_error'       => null
                        ]);
                    }

                    DB::table('prefix_geo_ip')->insert($to_insert);

                    \Log::debug("LOCUS/SETUP - Insert: $insert_count, Update: $update_count");
                });
        }
        catch(Exception $ex) {}

        return 0;
    }
}