<?php

namespace Database\Seeders;

use App\Models\Asns;
use App\Models\Goliath\GoliathAppliance;
use App\Models\Goliath\GoliathAttack;
use App\Models\Goliath\GoliathMetro;
use App\Models\Goliath\GoliathSubregion;
use App\Models\GroupPermission;
use App\Models\Mercury\MercuryGre;
use App\Models\Mercury\MercuryNode;
use App\Models\Organisation;
use App\Models\OrganisationExternalIdentities;
use App\Models\Prefixes;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

class DemonstrationSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {

        //Organisation
        DB::table('organisations')->insert([
            'name' => config('creatia.automation.main_organisation_name')
        ]);

        DB::table('asns')->insert([[
            'asn' => 137409,
            'organisation_id' => 1,
            'approved' => 1
        ], [
            'asn' => 139284,
            'organisation_id' => 1,
            'approved' => 1
        ]]);

        //Insert some permissions
        DB::table('groups')->insert([[
            'id' => 1,
            'name' => 'Creatia Standard User',
        ]]);

        foreach([
            '1' => ['provision.bgp.view', 'provision.bgp.write', 'goliath.l1.report', 'hook.view', 'hook.update', 'network.view', 'goliath.l1.view', 'goliath.l1.edit', 'goliath.l1.log', 'goliath.l2.view', 'goliath.l2.edit', 'goliath.l2.log', 'network.rename', 'network.delete', 'network.redirect-view', 'network.redirect-write', 'network.map', 'mercury.view', 'mercury.delete', 'compute.bgp.view', 'compute.bgp.tier1', 'compute.bgp.tier2', 'compute.bgp.tier3', 'compute.bgp.write', 'compute.bgp.delete']
        ] as $id => $perms) {
            foreach($perms as $perm) {
                GroupPermission::create([
                    'permission' => $perm, 'status' => 1, 'group_id' => $id
                ]);
            }
        }

        //Insert our users
        DB::table('users')->insert([[
            'name'          => 'Demonstration Account',
            'email'         => 'demonstration@securelayer.com',
            'created_at'    => now(),
            'updated_at'    => now(),
            'group_id'      => 1,
            'organisation_id' => 1,
            'password'      => Hash::make('demonstration'),
            'signup_token'   => '',
        ]]);

        OrganisationExternalIdentities::create([
            'identity' => 1,
            'key' => 'gsl',
            'organisation_id' => 1
        ]);

        // Insert regionality

        file_put_contents(storage_path('locations.json'), '[ { "identifier": "APAC", "name": "APAC - Asia-Pacific", "subregions": [ { "identifier": "guam", "metro": [ { "identifier": "rti", "name": "RTI - RTI Guam GNC" } ], "name": "GUAM - Guam" }, { "identifier": "hk", "metro": [ { "identifier": "eqxhk1", "name": "EQXHK1 - Equinix HK1" }, { "identifier": "iavmei", "name": "IAVMEI - iAdvantage MEGA-i" } ], "name": "HK - Hong Kong, China" }, { "identifier": "sg", "metro": [ { "identifier": "eqxsg3", "name": "EQXSG3 - Equinix SG3" } ], "name": "SG - Singapore" }, { "identifier": "ty", "metro": [ { "identifier": "eqxty8", "name": "EQXTY8 - Equinix TY8" }, { "identifier": "eqxty2", "name": "EQXTY2 - Equinix TY2" }, { "identifier": "eqxty15", "name": "EQXTY15 - Equinix TY15" } ], "name": "TY - Tokyo, Japan" }, { "identifier": "chc", "metro": [ { "identifier": "spkche", "name": "SPKCHE - Spark Exchange Christchurch" } ], "name": "CHC - Christchurch, New Zealand" }, { "identifier": "wlg", "metro": [ { "identifier": "spkwlc", "name": "SPKWLC - Spark Wellington Central" } ], "name": "WLG - Wellington, New Zealand" }, { "identifier": "kr", "metro": [ { "identifier": "desel1", "name": "DESEL1 - DigitalEdge SEL1" }, { "identifier": "knxdg1", "name": "KNXDG1 - KINX Dogok 1 Center" } ], "name": "KR - Korea" } ] }, { "identifier": "EMEA", "name": "EMEA - Europe, Middle East, Africa", "subregions": [ { "identifier": "ams", "metro": [ { "identifier": "imams1", "name": "IMAMS1 - Iron Mountain AMS-1" }, { "identifier": "eqxam5", "name": "EQXAM5 - Equinix AM5" }, { "identifier": "nikhef", "name": "NIKHEF - Nikhef" } ], "name": "AMS - Amsterdam, Netherlands" }, { "identifier": "fra", "metro": [ { "identifier": "eqxfr5", "name": "EQXFR5 - Equinix FR5" } ], "name": "FRA - Frankfurt, Germany" }, { "identifier": "lon", "metro": [ { "identifier": "thn", "name": "THN - Telehouse North" }, { "identifier": "thw", "name": "THW - Telehouse West" }, { "identifier": "eqxld8", "name": "EQXLD8 - Equinix LD8" } ], "name": "LON - London, England" }, { "identifier": "mrs", "metro": [ { "identifier": "ixmrs2", "name": "IXMRS2 - Interxion MRS2" } ], "name": "MRS - Marseilles, France" }, { "identifier": "par", "metro": [ { "identifier": "eqxpa3", "name": "EQXPA3 - Equinix PA3" }, { "identifier": "thpa2", "name": "THPA2 - Telehouse PA2" } ], "name": "PAR - Paris, France" }, { "identifier": "hel", "metro": [ { "identifier": "eqxhe5", "name": "EQXHE5 - Equinix HE5" }, { "identifier": "digdc9", "name": "DIGDC9 - Digita DC9" } ], "name": "HEL - Helsinki, Finland" }, { "identifier": "mad", "metro": [ { "identifier": "eqxmd2", "name": "EQXMD2 - Equinix MD2" } ], "name": "MAD - Madrid, Spain" }, { "identifier": "mil", "metro": [ { "identifier": "eqxml2", "name": "EQXML2 - Equinix ML2" }, { "identifier": "retav1gr", "name": "RETAV1GR - Retelit Avalon 1 Green" } ], "name": "MIL - Milan, Italy" }, { "identifier": "mus", "metro": [ { "identifier": "eqxmc1", "name": "EQXMC1 - Equinix MC1" } ], "name": "MUS - Muscat, Oman" }, { "identifier": "sof", "metro": [ { "identifier": "eqxso2", "name": "EQXSO2 - Equinix SO2" }, { "identifier": "tlpc", "name": "TLPC - TELEPOINT Sofia Centre" } ], "name": "SOF - Sofia, Bulgaria" }, { "identifier": "tai", "metro": [ { "identifier": "chly", "name": "CHLY - Chief LY Building Taipei" } ], "name": "TAI - Taipei, Taiwan" }, { "identifier": "vie", "metro": [ { "identifier": "ixvie1", "name": "IXVIE1 - Interxion VIE1" } ], "name": "VIE - Vienna, Austria" }, { "identifier": "war", "metro": [ { "identifier": "eqxwa1", "name": "EQXWA1 - Equinix WA1" } ], "name": "WAR - Warsaw, Poland" }, { "identifier": "tpe", "metro": [ { "identifier": "lyb", "name": "LYB - Chief LY Building Taipei" } ], "name": "TPE - Taipei, Taiwan" } ] }, { "identifier": "NA", "name": "NA - North America", "subregions": [ { "identifier": "ash", "metro": [ { "identifier": "eqxdc10", "name": "EQXDC10 - Equinix DC10" } ], "name": "ASH - Ashburn, VA, US" }, { "identifier": "atl", "metro": [ { "identifier": "drtatl1", "name": "DRTATL1 - Digital Realty ATL1" } ], "name": "ATL - Atlanta, GA, US" }, { "identifier": "chi", "metro": [ { "identifier": "eqxch1", "name": "EQXCH1 - Equinix CH1" }, { "identifier": "eqxch3", "name": "EQXCH3 - Equinix CH3" } ], "name": "CHI - Chicago, IL, US" }, { "identifier": "dal", "metro": [ { "identifier": "eqxda11", "name": "EQXDA11 - Equinix DA11" } ], "name": "DAL - Dallas, TX, US" }, { "identifier": "lax", "metro": [ { "identifier": "eqxla1", "name": "EQXLA1 - Equinix LA1" }, { "identifier": "csla1", "name": "CSLA1 - Coresite LA1" }, { "identifier": "csla2", "name": "CSLA2 - Coresite LA2" } ], "name": "LAX - Los Angeles, CA, US" }, { "identifier": "nyc", "metro": [ { "identifier": "165h", "name": "165H - 165 Halsey" }, { "identifier": "eqxny2", "name": "EQXNY2 - Equinix NY2" } ], "name": "NYC - New York, NY, US" }, { "identifier": "phx", "metro": [ { "identifier": "pnap", "name": "PNAP - PhoenixNAP" } ], "name": "PHX - Phoenix, AZ, US" }, { "identifier": "pit", "metro": [ { "identifier": "dbpit1", "name": "DBPIT1 - Databank PIT1" } ], "name": "PIT - Pittsburgh, PA, US" }, { "identifier": "sea", "metro": [ { "identifier": "eqxse2", "name": "EQXSE2 - Equinix SE2" }, { "identifier": "drtsea10", "name": "DRTSEA10 - Digital Realty SEA10" } ], "name": "SEA - Seattle, WA, US" }, { "identifier": "mia", "metro": [ { "identifier": "eqxmi1", "name": "EXQMI1 - Equinix MI1" } ], "name": "MIA - Miami, FL, US" } ] }, { "identifier": "Oceanic", "name": "OCEANIC - Australia + New Zealand", "subregions": [ { "identifier": "adl", "metro": [ { "identifier": "eqxae1", "name": "EQXAE1 - Equinix AE1" }, { "identifier": "ccdc3", "name": "CCDC3 - Colocity DC3" } ], "name": "ADL - Adelaide, Australia" }, { "identifier": "akl", "metro": [ { "identifier": "spkmdr", "name": "SPKMDR - Spark MDR" }, { "identifier": "dc220", "name": "DC220 - DataCentre220 Auckland" } ], "name": "AKL - Auckland, New Zealand" }, { "identifier": "bne", "metro": [ { "identifier": "ndcb2", "name": "NDCB2 - NextDC B2" }, { "identifier": "iskldr2", "name": "ISKLDR2 - iseek LDR2" } ], "name": "BNE - Brisbane, Australia" }, { "identifier": "mel", "metro": [ { "identifier": "ndcm1", "name": "NDCM1 - NextDC M1" }, { "identifier": "eqxme1", "name": "EQXME1 - Equinix ME1" } ], "name": "MEL - Melbourne, Australia" }, { "identifier": "per", "metro": [ { "identifier": "eqxpe2", "name": "EQXPE2 - Equinix PE2" }, { "identifier": "ndcp2", "name": "NDCP2 - NextDC P2" }, { "identifier": "ndcp1", "name": "NDCP1 - NextDC P1" } ], "name": "PER - Perth, Australia" }, { "identifier": "syd", "metro": [ { "identifier": "eqxsy5", "name": "EQXSY5 - Equinix SY5" }, { "identifier": "ndcs1", "name": "NDCS1 - NextDC S1" } ], "name": "SYD - Sydney, Australia" } ] } ]');

        Artisan::call('location:update');

        // Insert mercury nodes

        foreach([
            ["London", "LON ", "38.57.36.21", "2401:3cc0:100d:1::2"],
            ["Amsterdam", "AMS ", "38.57.36.9", "2401:3cc0:100e:1::2"],
            ["Frankfurt", "FRA ", "38.57.36.11", "2401:3cc0:13:1::2"],
            ["Paris", "PAR ", "38.57.36.19", "2401:3cc0:24:1::2"],
            ["Madrid", "MAD ", "38.57.36.17", "2401:3cc0:25:1::2"],
            ["Marseille", "MAR ", "38.57.36.15", "2401:3cc0:1011::2"],
            ["Sofia", "SOF ", "38.57.36.1", "2401:3cc0:28:1::2"],
            ["Vienna", "VIE ", "38.57.36.3", "2401:3cc0:2a:1::2"],
            ["Warsaw", "WAR ", "38.57.36.5", "2401:3cc0:27:1::2"],
            ["Helsinki", "HEL ", "38.57.36.7", "2401:3cc0:29:2::2"],
            ["Milan", "MIL ", "38.57.36.13", "2401:3cc0:26:2::2"],
            ["New York", "NYC ", "38.57.36.79", "2401:3cc0:840:4::2"],
            ["Ashburn ", "ASH ", "38.57.36.73", "2401:3cc0:1013:1::2"],
            ["Atlanta", "ATL ", "38.57.36.71", "2401:3cc0:1014:1::2"],
            ["Miami", "MIA ", "38.57.36.75", "2401:3cc0:1018:1::2"],
            ["Pittsburgh", "PITS ", "38.57.36.77", "2401:3cc0:1019:1::2"],
            ["Chicago", "CHI ", "38.57.36.67", "2401:3cc0:100b:1::2"],
            ["Dallas", "DAL ", "38.57.36.69", "2401:3cc0:100c:1::2"],
            ["Phoenix", "PHX ", "38.57.36.59", "2401:3cc0:1015:1::2"],
            ["Los Angeles", "LA ", "38.57.36.57", "2401:3cc0:900:1::2"],
            ["Seattle", "SEA ", "38.57.36.55", "2401:3cc0:100a:1::2"],
            ["Tokyo", "TY ", "38.57.36.33", "2401:3cc0:800:3::2"],
            ["Taipei", "TPE ", "38.57.36.29", "2401:3cc0:101a:1::2"],
            ["Hong Kong", "HK ", "38.57.36.27", "2401:3cc0:1016:1::2"],
            ["Singapore", "SG ", "38.57.36.25", "2401:3cc0:600:3::2"],
            ["Muscat", "MCT ", "38.57.36.23", "2401:3cc0:1017:1::2"]
        ] as $node) {
            MercuryNode::create([ 'name' => $node[0], 'tag' => $node[1], 'server_v4' => $node[2], 'server_v6' => $node[3] ]);
        }

        foreach(GoliathSubregion::all() as $subregion) {

            $relevant_datacentre = GoliathMetro::where([ ['subregion_id', '=', $subregion->id], ['telemetry_identifier', 'LIKE', 'eqx%'] ])->get()->first();

            if($relevant_datacentre !== null) {
                GoliathAppliance::create([
                    'organisation_id' => 1,
                    'region_id' => $subregion->region_id,
                    'subregion_id' => $subregion->id,
                    'metro_id' => $relevant_datacentre->id,
                    'name' => "$subregion->name",
                    'address' => '10.100.' . rand(0, 255) . '.' . rand(0, 250)
                ]);
            }
        }


        // Insert some prefixes
        Prefixes::factory()->address('103.1.213.13', 32)->name('')->ownership(Organisation::find(1), Asns::find(1))->inline(true)->flags(2, true, false)->create();
        Prefixes::factory()->address('103.1.213.0', 24)->name('')->ownership(Organisation::find(1), Asns::find(1))->inline(false)->flags(3, false, false)->create();

        Prefixes::factory()->address('203.15.120.57', 32)->name('')->ownership(Organisation::find(1), Asns::find(1))->inline(false)->flags(3, false, false)->create();
        Prefixes::factory()->address('203.15.120.0', 24)->name('')->ownership(Organisation::find(1), Asns::find(1))->inline(false)->flags(3, true, false)->create();

        // Insert a tunnel

        MercuryGre::create([
            'organisation_id' => 1,
            'asn_id' => 1,
            'node_id' => 1,
            'name' => 'Example Tunnel #1',
            'client_address' => '103.1.213.13',
            'gsl_device_v4' => '10.0.4.11',
            'gsl_device_v6' => '2401:3bc0::4:13',
            'client_device_v4' => '10.0.4.12',
            'client_device_v6' => '2401:3bc0::4:14',
            'filter' => 'asn',
            'mtu' => 1350,
            'tunnel_number' => 0
        ]);

        // Insert two attack events
        GoliathAttack::create([
            'destination'   => '103.1.213.13',
            'type'          => 'UDP Flood',
            'description'   => 'UDP Flood',
            'region_id'     => 4,
            'subregion_id'  => 37,
            'metro_id'      => 60,
            'appliance_id'  => GoliathAppliance::where([['region_id', '=', 4], ['subregion_id', '=', 37], ['metro_id', '=', 60]])->get()->first()->id, 
            'started_at'    => Carbon::parse('2025-06-18 22:44:19'),
            'last_at'       => Carbon::parse('2025-06-18 22:45:26'),
        ]);

        GoliathAttack::create([
            'destination'   => '203.15.120.57',
            'type'          => 'UDP Flood',
            'description'   => 'UDP Flood',
            'region_id'     => 4,
            'subregion_id'  => 37,
            'metro_id'      => 60,
            'appliance_id'  => GoliathAppliance::where([['region_id', '=', 4], ['subregion_id', '=', 37], ['metro_id', '=', 60]])->get()->first()->id, 
            'started_at'    => Carbon::parse('2025-07-20 04:56:59'),
            'last_at'       => Carbon::parse('2025-07-20 05:08:34'),
        ]);

        Artisan::call('prefix:sort');
        Artisan::call('goliath:monitor-attacks', ['--thread-pool' => 1, '--minutes' => 6]);

    }
}
