<?php

class Carriers {

    const CARRIER_REGEXES = [
        [
            "carrier" => "usps_gsbarcode", // USPS barcodes with GS character
            "pattern" => "/^\\x1D?420[0-9]{5,11}\\x1D?[0-9]{10,}\\x1D?$/"
        ],
        [
            "carrier" => "ups_mi_datamatrix",
            "pattern" => "/^([^\\t]*\\t[^\\t]*){13}$/"
        ],
        [
            "carrier" => "fedex_pdf417",
            "pattern" => "/.*\\x1D.*\\x1D.*\\x1D.*/" // look for the GS (group seperator) multiple times
        ],
        [
            "carrier" => "helena_express",
            "pattern" => "/^[HLN|HEX][0-9]+$/"
        ],
        [
            "carrier" => "helena_express",
            "pattern" => "/^406[0-9]{6}$/"
        ],
        [
            "carrier" => "helena_express",
            "pattern" => "/^406[0-9]{9}$/"
        ],
        [
            "carrier" => "usps",
            "pattern" => "/^[0-9]{20,40}$/"
        ],
        [
            "carrier" => "usps",
            "pattern" => "/^82[0-9]{8}$/"
        ],
        [
            "carrier" => "usps",
            "pattern" => "/^E\D{1}\d{9}\D{2}$|^9\d{15,21}$/"
        ],
        [
            "carrier" => "usps",
            "pattern" => "/^91[0-9]{12,}+$/"
        ],
        [
            "carrier" => "usps",
            "pattern" => "/^[A-Z]{2}[0-9]{9}[A-Z]{2}$/"
        ],
        [
            "carrier" => "usps",
            "pattern" => "/^420[0-9]{5}[0-9]+$/"
        ],
        [
            "carrier" => "fedex",
            "pattern" => "/^[0-9]{15}$/"
        ],
        [
            "carrier" => "fedex",
            "pattern" => "/^[0-9]{12}$/"
        ],
        [
            "carrier" => "ups",
            "pattern" => "/\b(1Z ?[0-9A-Z]{3} ?[0-9A-Z]{3} ?[0-9A-Z]{2} ?[0-9A-Z]{4} ?[0-9A-Z]{3} ?[0-9A-Z]|[\dT]\d\d\d ?\d\d\d\d ?\d\d\d)\b/"
        ],
        [
            "carrier" => "ups",
            "pattern" => "/^[KJ]{1}[0-9]{10}$/"
        ],
        [
            "carrier" => "fedex",
            "pattern" => "/(\b96\d{20}\b)|(\b\d{15}\b)|(\b\d{12}\b)/"
        ],
        [
            "carrier" => "fedex",
            "pattern" => "/\b((98\d\d\d\d\d?\d\d\d\d|98\d\d) ?\d\d\d\d ?\d\d\d\d( ?\d\d\d)?)\b/"
        ],
        [
            "carrier" => "dhl_express",
            "pattern" => "/^[0-9]{10}$/"
        ],
        [
            "carrier" => "dhl_express",
            "pattern" => "/^J?JD[0-9]{13,18}$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^[LR][A-Z][0-9]{9}DE$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^CNAOG[0-9]{10}$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^SGKEN[0-9]{10}$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^SGAGS[0-9]{6}$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^[0-9]{16}$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^[0-9]{22}$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^GM[0-9]{16,18}$/"
        ],
        [
            "carrier" => "dhl_ecommerce",
            "pattern" => "/^A[A-Z0-9]000[0-9]{15}$/"
        ],
        [
            "carrier" => "lasership",
            "pattern" => "/^LX[0-9]+$/"
        ],
        [
            "carrier" => "lasership",
            "pattern" => "/^1LS[0-9]+$/"
        ],
    ];
    const CARRIERS = [
        "usps" => [
            "code" => "usps",
            "name" => "USPS"
        ],
        "ups" => [
            "code" => "ups",
            "name" => "UPS"
        ],
        "upsdap" => [
            "code" => "ups",
            "name" => "UPS"
        ],
        "ups_mi_datamatrix" => [
            "code" => "usps",
            "name" => "USPS"
        ],
        "fedex" => [
            "code" => "fedex",
            "name" => "FedEx"
        ],
        "fedex_pdf417" => [
            "code" => "fedex",
            "name" => "FedEx"
        ],
        "dhl_express" => [
            "code" => "dhl_express",
            "name" => "DHL Express"
        ],
        "dhlexpress" => [
            "code" => "dhl_express",
            "name" => "DHL Express"
        ],
        "dhl_ecommerce" => [
            "code" => "dhl_ecommerce",
            "name" => "DHL eCommerce"
        ],
        "lasership" => [
            "code" => "lasership",
            "name" => "LaserShip"
        ],
        "helena_express" => [
            "code" => "helena_express",
            "name" => "Helena Express"
        ]
    ];
    const CARRIER_TRACKING_URLS = [
        "usps" => "https://tools.usps.com/go/TrackConfirmAction?qtc_tLabels1={{number}}",
        "ups" => "https://wwwapps.ups.com/WebTracking/processInputRequest?tracknum={{number}}",
        "fedex" => "https://www.fedex.com/fedextrack/?trknbr={{number}}",
        "dhl_express" => "https://mydhl.express.dhl/us/en/tracking.html#/results?id={{number}}",
        "helena_express" => "https://helena.express/track#{{number}}"
    ];

    public static function getCarrierName(string $carrier): string {
        // scan by internal ID
        foreach (Carriers::CARRIERS as $id => $info) {
            if ($id == $carrier) {
                return $info["name"];
            }
        }
        // scan by code
        foreach (Carriers::CARRIERS as $id => $info) {
            if (strtolower($info["code"]) == strtolower($carrier)) {
                return $info["name"];
            }
        }
        return $carrier;
    }

    public static function getCarrierCode(string $carrier): string {
        // scan by internal ID
        foreach (Carriers::CARRIERS as $id => $info) {
            if ($id == $carrier) {
                return $info["code"];
            }
        }
        // scan by name
        foreach (Carriers::CARRIERS as $id => $info) {
            if (strtolower($info["name"]) == strtolower($carrier)) {
                return $info["code"];
            }
        }
        return "";
    }

    public static function getCarrierTrackingUrl($carrier, $code) {
        $carrier = Carriers::getCarrierCode($carrier);
        if (!empty(Carriers::CARRIER_TRACKING_URLS[$carrier])) {
            return str_replace("{{number}}", $code, Carriers::CARRIER_TRACKING_URLS[$carrier]);
        }
        return false;
    }

}
