<?php

namespace App\Console\Commands\Network;

use App\Console\Commands\BaseCommand;

use App\Models\Goliath\GoliathRegion;
use App\Models\Goliath\GoliathSubregion;
use App\Models\Goliath\GoliathMetro;
use Illuminate\Support\Facades\DB;

class LocationUpdate extends BaseCommand
{

    protected $signature = 'location:update';

    protected $description = 'Updates the location list that exists based upon what is in telemetry.';

    public function handleNotEnterprise() {
        $db = new \ClickHouseDB\Client([
            'host'      => config('creatia.clickhouse.endpoint'),
            'port'      => config('creatia.clickhouse.port'),
            'username'  => config('creatia.clickhouse.user'),
            'password'  => config('creatia.clickhouse.password'),
	        'readonly'  => true
        ]);

        $db->database( config('creatia.clickhouse.database') );
        $db->setTimeout(1.5);      // 1 second , support only Int value
        $db->setTimeout(10);       // 10 seconds
        $db->setConnectTimeOut(10); // 5 seconds
        $db->ping(true); // if can`t connect throw exception

        $stmt_regions = $db->select("SELECT * FROM regions");
        $stmt_metros = $db->select("SELECT * FROM metros");
        $stmt_facilities = $db->select("SELECT * FROM facilities");

        $res_regions = $stmt_regions->rawData();
        $res_metros = $stmt_metros->rawData();
        $res_facilities = $stmt_facilities->rawData();

        $all_regions = GoliathRegion::all()->keyBy('telemetry_identifier');
        $all_subregions = GoliathSubregion::all()->keyBy('telemetry_identifier');
        $all_metros = GoliathMetro::all()->keyBy('telemetry_identifier');

        $insert_regions = [];
        $insert_subregions = [];
        $insert_metros = [];

        foreach($res_regions['data'] as $region) {
            if(!isset($all_regions[$region['name']])) {
                $insert_regions[] = [
                    'name' => strtoupper($region['name']) . ' - ' . $region['description'],
                    'telemetry_identifier' => $region['name'],
                    'visible' => 1
                ];
            }
        }

        DB::table('goliath_regions')->insert($insert_regions);
        $all_regions = GoliathRegion::all()->keyBy('telemetry_identifier');

        foreach($res_metros['data'] as $subregion) {
            if(!isset($all_subregions[$subregion['name']])) {
                $insert_subregions[] = [
                    'name' => strtoupper($subregion['name']) . ' - ' . $subregion['description'],
                    'telemetry_identifier' => $subregion['name'],
                    'visible' => 1,
                    'region_id' => $all_regions[$subregion['region']]->id
                ];
            }
        }

        DB::table('goliath_subregions')->insert($insert_subregions);
        $all_subregions = GoliathSubregion::all()->keyBy('telemetry_identifier');

        foreach($res_facilities['data'] as $metro) {
            if(!isset($all_metros[$metro['name']])) {
                $insert_metros[] = [
                    'name' => strtoupper($metro['name']) . ' - ' . $metro['description'],
                    'telemetry_identifier' => $metro['name'],
                    'visible' => 1,
                    'subregion_id' => $all_subregions[$metro['metro']]->id
                ];
            }
        }

        DB::table('goliath_metro')->insert($insert_metros);

        return true;
    }

    public function handleEnterprise() {

        $locations = json_decode(file_get_contents(storage_path('locations.json')), true);

        $all_regions = GoliathRegion::all()->keyBy('telemetry_identifier');
        $all_subregions = GoliathSubregion::all()->keyBy('telemetry_identifier');
        $all_metros = GoliathMetro::all()->keyBy('telemetry_identifier');

        foreach($locations as $region) {
            
            // Create region and update list if the region does not yet exist.
            if(!isset($all_regions[$region['identifier']])) {
                GoliathRegion::create([
                    'name'                  => $region['name'],
                    'visible'               => 1,
                    'telemetry_identifier'  => $region['identifier']
                ]);

                $all_regions = GoliathRegion::all()->keyBy('telemetry_identifier');
            }

            foreach($region['subregions'] as $subregion) {

                // Create region and update list if the region does not yet exist.
                if(!isset($all_subregions[$subregion['identifier']])) {
                    GoliathSubregion::create([
                        'name'                  => $subregion['name'],
                        'visible'               => 1,
                        'telemetry_identifier'  => $subregion['identifier'],
                        'region_id'             => $all_regions[$region['identifier']]->id
                    ]);

                    $all_subregions = GoliathSubregion::all()->keyBy('telemetry_identifier');
                }

                foreach($subregion['metro'] as $metro) {

                    // Create region and update list if the region does not yet exist.
                    if(!isset($all_metros[$metro['identifier']])) {
                        GoliathMetro::create([
                            'name'                  => $metro['name'],
                            'visible'               => 1,
                            'telemetry_identifier'  => $metro['identifier'],
                            'subregion_id'             => $all_subregions[$subregion['identifier']]->id
                        ]);

                        $all_metros = GoliathMetro::all()->keyBy('telemetry_identifier');
                    }
                }
            }
        }


    }

    public function handle()
    {

        $x = false;

        if(!config('app.enterprise') && !config('app.demonstration')) {
            $x = $this->handleNotEnterprise();
        }
        else {
            $x = $this->handleEnterprise();
        }

        return $x ? 1 : 0;
    }
}
