<?php

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

$hash = sha1(($VARS["number"] ?? "") . "|" . ($VARS["unit"] ?? "") . "|" . ($VARS["street"] ?? ""). "|" . ($VARS["city"] ?? "") . "|" . ($VARS["state"] ?? "") . "|" . ($VARS["zip"] ?? ""));
$cacheresp = $memcache->get("logistics.uspsaddress." . $hash);
if ($cacheresp !== false && empty($VARS["nocache"])) {
    exitWithJson(json_decode($cacheresp, true));
}

$output = [
    "status" => "OK",
    "address" => [
        "status" => "",
        "message" => "",
        "address" => "",
        "zip" => "",
        "plus4" => "",
        "delivery_point" => "",
        "route" => "",
        "county" => "",
        "dpv_confirmed" => false,
        "cmra" => false,
        "business" => false,
        "centralized" => false,
        "vacant" => false
    ]
];

try {

    if (empty($VARS["state"])) {
        throw new Exception("A state is required.");
    }
    if (empty($VARS["zip"]) && empty($VARS["city"])) {
        throw new Exception("A city and/or ZIP Code are required.");
    }

    $VARS["state"] = trim(strtoupper($VARS["state"]));
    $statereg = "/^(AA|AE|AL|AK|AP|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MP|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY)$/";
    if (!preg_match($statereg, $VARS["state"])) {
        throw new Exception("Two-letter state name is required.");
    }
    if (!empty($VARS["number"]) && !empty($VARS["street"])) {
        $streetAddress = urldecode($VARS["number"]) . " " . urldecode($VARS["street"]);
    } else if (!empty($VARS["street"])) {
        $streetAddress = urldecode($VARS["street"]);
    } else {
        $streetAddress = "";
    }

    $request = "addresses/v3/address?streetAddress=" . urlencode($streetAddress)
            . (!empty($VARS["unit"]) ? "&secondaryAddress=" . urlencode(urldecode($VARS["unit"])) : "")
            . (!empty($VARS["city"]) ? "&city=" . urlencode(urldecode($VARS["city"])) : "&city=")
            . (!empty($VARS["state"]) ? "&state=" . urlencode(urldecode($VARS["state"])) : "&state=")
            . (!empty($VARS["zip"]) ? "&ZIPCode=" . urlencode(urldecode($VARS["zip"])) : "");
    $resp = USPSAPIs::getAPIRequest($request);

    $json = json_decode($resp, true);

    if (!empty($json["error"])) {
        if (!empty($json["error"]["message"])) {
            throw new Exception(trim($json["error"]["message"]));
        }
        throw new Exception("The USPS system is having problems. Try again later.");
    }

    $addr = $json["address"];
    $addl = $json["additionalInfo"];

    $output["address"]["address"] = $addr["streetAddress"] . (!empty($addr["secondaryAddress"]) ? " " . $addr["secondaryAddress"] : "");
    $output["address"]["city"] = $addr["city"];
    $output["address"]["state"] = $addr["state"];
    $output["address"]["zip"] = $addr["ZIPCode"];
    $output["address"]["plus4"] = $addr["ZIPPlus4"] ?? "";

    $output["address"]["delivery_point"] = (empty($addl["deliveryPoint"]) ? "" : $addl["deliveryPoint"]);
    $output["address"]["route"] = $addl["carrierRoute"];
    $output["address"]["county"] = ""; // Not implemented in API but a value is expected by some clients
    $output["address"]["dpv_confirmed"] = $addl["DPVConfirmation"] == "Y";
    $output["address"]["cmra"] = ($addl["DPVCMRA"] ?? "") == "Y";
    $output["address"]["business"] = $addl["business"] == "Y";
    $output["address"]["centralized"] = $addl["centralDeliveryPoint"] == "Y";
    $output["address"]["vacant"] = $addl["vacant"] == "Y";

    $output["address"]["status"] = "OK";

    $memcache->set("logistics.uspsaddress." . $hash, json_encode($output));
} catch (Exception $ex) {
    $output["address"]["status"] = "ERROR";
    $output["address"]["message"] = $ex->getMessage();
}

exitWithJson($output);
