<?php

namespace App\Rules;

use App\Helpers\Utility\WhoIs as UtilityWhoIs;
use App\Models\Asns;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\Auth;

class WhoIs implements Rule
{
    protected $type = 'asn';
    protected $admin_bypass = false;

    /**
     * Create a new rule instance.
     *
     * @param string $_type - asn | as-set
     * @param bool $_admin_bypass
     */
    public function __construct(string $_type, bool $_admin_bypass = false)
    {
        $this->type = $_type;
        $this->admin_bypass = $_admin_bypass;
    }

    /**
     * Static constructor for cleaner syntax
     *
     * @param string $_type - asn | as-set
     * @param bool $_admin_bypass
     * @return static
     */
    public static function make(string $_type, bool $_admin_bypass)
    {
        return new static($_type, $_admin_bypass);
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value - [ asn => string|integer, email => string ] | string
     * @return bool
     */
    public function passes($attribute, $value)
    {

        if($this->type === 'asn') {

            [ $asn, $email ] = $value;

            $asn_emails = UtilityWhoIs::asn_emails($asn);

            return $this->admin_bypass ? ($asn_emails !== false) : in_array($email, $asn_emails);

        }

        if($this->type === 'as-set') {

            // First, extract the top level ASN if it's present - Otherwise we fail.
            $nested_asn = str_contains($value, ':') === true ? explode(':', $value)[0] : false;

            if(!$nested_asn) {
                return false;
            }

            $top_level_owned = Asns::where('asn', '=', ltrim($nested_asn, 'ASas'));

            if(!$this->admin_bypass) {
                $top_level_owned = $top_level_owned->where([['organisation_id', '=', Auth::user()->organisation_id], ['approved', '=', 1]]);
            }
            
            $top_level_owned = $top_level_owned->count() > 0;

            if(!$top_level_owned) {
                return false;
            }

            $as_set_exists = UtilityWhoIs::as_set_exists($value);

            return $as_set_exists;

        }

        return false;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The :attribute must correlate to an entry within a WHO-IS database.';
    }
}