<?php

namespace App\Development\Bgp;

use Carbon\Carbon;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

// bgp_microservice mock - port scans, live session details, PeeringDB prefill and session provisioning.
class Transit
{
    // Every port / circuit allocated to a customer (cxid = the org's gsl identity).
    public function scan(array $params, Request $request)
    {
        $scans = json_decode(file_get_contents(app_path('Development/Bgp/Cxid.json')), true);

        return Http::response($scans[Str::afterLast($request->url(), '/')] ?? [], 200);
    }

    // Live per-interface detail and BGP sessions for a scanned port (by temp_id).
    public function details(array $params, Request $request)
    {
        $details = json_decode(file_get_contents(app_path('Development/Bgp/Port.json')), true);

        return Http::response($details[Str::afterLast($request->url(), '/')] ?? [], 200);
    }

    // Accepts a new BGP session request asynchronously
    public function provision(array $params, Request $request)
    {
        return Http::response([
            'job_id'    => 'development-session-' . (crc32(explode('/', Str::afterLast($request->url(), '/custview/'))[0]) % 2) . '-' . time(),
            'status'    => 'running',
            'message'   => 'Provisioning in progress'
        ]);
    }

    // Port configuration context - LAGs (members, shape_rate), candidates, creatable ports (by temp_id).
    public function port_config(array $params, Request $request)
    {
        $configs = json_decode(file_get_contents(app_path('Development/Bgp/PortConfig.json')), true);

        $uuid = explode('/', Str::afterLast($request->url(), '/custview/'))[0];

        return Http::response($configs[$uuid] ?? $configs['default'], 200);
    }

    // Applies (or clears) the tx-queue 0 shape rate on the port's physical members.
    public function lp_limit(array $params, Request $request)
    {
        return Http::response([
            'success'        => true,
            'interface_name' => 'Port-Channel members'
        ]);
    }

    // Adds/removes a LAG member.
    public function lag_member(array $params, Request $request)
    {
        return Http::response([
            'success' => true
        ]);
    }

    // Converts a port into a new single-member LACP LAG.
    public function lag_create(array $params, Request $request)
    {
        return Http::response([
            'success'      => true,
            'port_channel' => 'Port-Channel' . (crc32($request['interface'] ?? '') % 100)
        ]);
    }

    // Creates an inbound target tag for partner EVC provisioning.
    public function target_create(array $params, Request $request)
    {
        return Http::response([
            'code' => 'TGT-' . strtoupper(substr(hash('crc32b', $request->url() . ($request['vlan'] ?? '')), 0, 6)),
            'vlan' => $request['vlan'] ?? null
        ]);
    }

    // Looks up a partner target tag - always active in development.
    public function target_lookup(array $params, Request $request)
    {
        return Http::response([
            'code'      => Str::afterLast($request->url(), '/'),
            'status'    => 'active',
            'vlan'      => 601,
            'sid'       => 'ORG-B-50001',
            'device'    => 'sg-eqxsg3-cr7',
            'interface' => 'Ethernet19/1'
        ]);
    }

    // Returns information about a session that was async provisioned
    public function job_status(array $params, Request $request)
    {
        $time = (int)Str::afterLast(Str::afterLast($request->url(), '/'), '-');

        $general_response = [
            'job_id'    => Str::afterLast($request->url(), '/'),
            'kind'      => 'bgp-session',
            'detail'    => null,
            'result'    => null
        ];

        if($time < (time() - 5)) {
            return Http::response([
                ...$general_response,
                'status'    => 'complete',
                'message'   => 'Provisioning in progress'
            ]);
        }

        return Http::response([
            ...$general_response,
            'status'    => 'running',
            'message'   => 'Provisioning Complete'
        ]);
    }
}
