<?php
/**
 * ResourcesApi
 * PHP version 5
 *
 * @category Class
 * @package  USPS\InternationalLabels
 * @author   Swagger Codegen team
 * @link     https://github.com/swagger-api/swagger-codegen
 */

/**
 * International Labels
 *
 * Contact Us: [USPS API Support](https://emailus.usps.com/s/usps-APIs) | [Terms of Service](https://about.usps.com/termsofuse.htm)  The USPS&#174; International Labels API allows you to digitally create mailing labels for `FIRST-CLASS_PACKAGE_INTERNATIONAL_SERVICE`, `PRIORITY_MAIL_INTERNATIONAL`, and `PRIORITY_MAIL_EXPRESS_INTERNATIONAL`.  * Use the [Getting Started guide](https://developers.usps.com/getting-started) to get started with the Labels API. * The USPS&#174; International Labels API uses a token to authorize the use of an [Enterprise Payment](https://postalpro.usps.com/EPS) or Permit account. The specification to generate the token is in the [Payments 3.0 - Set Payment Account Information](https://developers.usps.com/paymentsv3#tag/Resources/operation/post-payments-payment-authorization).  **References**: * [Publication 199](http://postalpro.usps.com/pub199) * [Publication 205](http://postalpro.usps.com/pub205)  **Manifest Scheduling**   The following table outlines the International Label manifesting schedule for specific conditions listed below.   | Condition                   | Scheduling | | ----------------------------| -------- | | **Value of `true` provided for `immediateManifest` field**| Electronic data is sent to Postal systems within 15 minutes of label creation.  | | **Label is added to a [SCAN Form](https://developers.usps.com/scanv3#tag/Resources/operation/post-scan-form)**| Electronic data is sent to Postal systems within 15 minutes of SCAN Form creation.  | | **All other conditions**    | 12:30am CT on the day after label creation. |
 *
 * OpenAPI spec version: 3.3.4
 * 
 * Generated by: https://github.com/swagger-api/swagger-codegen.git
 * Swagger Codegen version: 3.0.71
 */
/**
 * NOTE: This class is auto generated by the swagger code generator program.
 * https://github.com/swagger-api/swagger-codegen
 * Do not edit the class manually.
 */

namespace USPS\InternationalLabels\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use USPS\InternationalLabels\ApiException;
use USPS\InternationalLabels\Configuration;
use USPS\InternationalLabels\HeaderSelector;
use USPS\InternationalLabels\ObjectSerializer;

/**
 * ResourcesApi Class Doc Comment
 *
 * @category Class
 * @package  USPS\InternationalLabels
 * @author   Swagger Codegen team
 * @link     https://github.com/swagger-api/swagger-codegen
 */
class ResourcesApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var Configuration
     */
    protected $config;

    /**
     * @var HeaderSelector
     */
    protected $headerSelector;

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     */
    public function __construct(
        ClientInterface $client = null,
        Configuration $config = null,
        HeaderSelector $selector = null
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: new Configuration();
        $this->headerSelector = $selector ?: new HeaderSelector();
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation deleteInternationalLabel
     *
     * Cancel a previously requested label or request a refund on label
     *
     * @param  string $tracking_number The unique tracking number of the label. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \USPS\InternationalLabels\Model\CancelResponse
     */
    public function deleteInternationalLabel($tracking_number, $x_payment_authorization_token)
    {
        list($response) = $this->deleteInternationalLabelWithHttpInfo($tracking_number, $x_payment_authorization_token);
        return $response;
    }

    /**
     * Operation deleteInternationalLabelWithHttpInfo
     *
     * Cancel a previously requested label or request a refund on label
     *
     * @param  string $tracking_number The unique tracking number of the label. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \USPS\InternationalLabels\Model\CancelResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteInternationalLabelWithHttpInfo($tracking_number, $x_payment_authorization_token)
    {
        $returnType = '\USPS\InternationalLabels\Model\CancelResponse';
        $request = $this->deleteInternationalLabelRequest($tracking_number, $x_payment_authorization_token);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\CancelResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 503:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation deleteInternationalLabelAsync
     *
     * Cancel a previously requested label or request a refund on label
     *
     * @param  string $tracking_number The unique tracking number of the label. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteInternationalLabelAsync($tracking_number, $x_payment_authorization_token)
    {
        return $this->deleteInternationalLabelAsyncWithHttpInfo($tracking_number, $x_payment_authorization_token)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation deleteInternationalLabelAsyncWithHttpInfo
     *
     * Cancel a previously requested label or request a refund on label
     *
     * @param  string $tracking_number The unique tracking number of the label. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteInternationalLabelAsyncWithHttpInfo($tracking_number, $x_payment_authorization_token)
    {
        $returnType = '\USPS\InternationalLabels\Model\CancelResponse';
        $request = $this->deleteInternationalLabelRequest($tracking_number, $x_payment_authorization_token);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteInternationalLabel'
     *
     * @param  string $tracking_number The unique tracking number of the label. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function deleteInternationalLabelRequest($tracking_number, $x_payment_authorization_token)
    {
        // verify the required parameter 'tracking_number' is set
        if ($tracking_number === null || (is_array($tracking_number) && count($tracking_number) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_number when calling deleteInternationalLabel'
            );
        }
        // verify the required parameter 'x_payment_authorization_token' is set
        if ($x_payment_authorization_token === null || (is_array($x_payment_authorization_token) && count($x_payment_authorization_token) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $x_payment_authorization_token when calling deleteInternationalLabel'
            );
        }

        $resourcePath = '/international-label/{trackingNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($x_payment_authorization_token !== null) {
            $headerParams['X-Payment-Authorization-Token'] = ObjectSerializer::toHeaderValue($x_payment_authorization_token);
        }

        // path params
        if ($tracking_number !== null) {
            $resourcePath = str_replace(
                '{' . 'trackingNumber' . '}',
                ObjectSerializer::toPathValue($tracking_number),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json', 'application/xml']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json', 'application/xml'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation postInternationalIndicia
     *
     * Create a First-Class Mail International letter, flat, or card indicia
     *
     * @param  map[string,object] $body Indicia request payload containing necessary data for generating a First-Class Mail International indicia. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \USPS\InternationalLabels\Model\IndiciaResponse
     */
    public function postInternationalIndicia($body, $x_payment_authorization_token)
    {
        list($response) = $this->postInternationalIndiciaWithHttpInfo($body, $x_payment_authorization_token);
        return $response;
    }

    /**
     * Operation postInternationalIndiciaWithHttpInfo
     *
     * Create a First-Class Mail International letter, flat, or card indicia
     *
     * @param  map[string,object] $body Indicia request payload containing necessary data for generating a First-Class Mail International indicia. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \USPS\InternationalLabels\Model\IndiciaResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function postInternationalIndiciaWithHttpInfo($body, $x_payment_authorization_token)
    {
        $returnType = '\USPS\InternationalLabels\Model\IndiciaResponse';
        $request = $this->postInternationalIndiciaRequest($body, $x_payment_authorization_token);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 201:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\IndiciaResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 503:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation postInternationalIndiciaAsync
     *
     * Create a First-Class Mail International letter, flat, or card indicia
     *
     * @param  map[string,object] $body Indicia request payload containing necessary data for generating a First-Class Mail International indicia. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function postInternationalIndiciaAsync($body, $x_payment_authorization_token)
    {
        return $this->postInternationalIndiciaAsyncWithHttpInfo($body, $x_payment_authorization_token)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation postInternationalIndiciaAsyncWithHttpInfo
     *
     * Create a First-Class Mail International letter, flat, or card indicia
     *
     * @param  map[string,object] $body Indicia request payload containing necessary data for generating a First-Class Mail International indicia. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function postInternationalIndiciaAsyncWithHttpInfo($body, $x_payment_authorization_token)
    {
        $returnType = '\USPS\InternationalLabels\Model\IndiciaResponse';
        $request = $this->postInternationalIndiciaRequest($body, $x_payment_authorization_token);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'postInternationalIndicia'
     *
     * @param  map[string,object] $body Indicia request payload containing necessary data for generating a First-Class Mail International indicia. (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function postInternationalIndiciaRequest($body, $x_payment_authorization_token)
    {
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling postInternationalIndicia'
            );
        }
        // verify the required parameter 'x_payment_authorization_token' is set
        if ($x_payment_authorization_token === null || (is_array($x_payment_authorization_token) && count($x_payment_authorization_token) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $x_payment_authorization_token when calling postInternationalIndicia'
            );
        }

        $resourcePath = '/indicia';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($x_payment_authorization_token !== null) {
            $headerParams['X-Payment-Authorization-Token'] = ObjectSerializer::toHeaderValue($x_payment_authorization_token);
        }


        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['multipart/form-data', 'application/json', 'application/xml', 'application/vnd.usps.labels+json', 'application/vnd.usps.labels+xml']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['multipart/form-data', 'application/json', 'application/xml', 'application/vnd.usps.labels+json', 'application/vnd.usps.labels+xml'],
                ['application/json', 'application/xml']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation postInternationalLabel
     *
     * Create a international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\InternationalLabelRequest $body body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $x_idempotency_key A unique UUID that serves as an idempotency key for safe request retries and duplicate charge prevention during label creation. This value must be a randomly generated UUID and unique per customer (CRID) across all label creation requests. When the same idempotency key is resubmitted with an identical request payload, the API will return the existing label without creating a duplicate or charging additional postage. The UUID will be included in the electronic manifest data (Shipping Services File D5 field) sent to Postal systems. (optional)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \USPS\InternationalLabels\Model\InternationalLabelResponse
     */
    public function postInternationalLabel($body, $x_payment_authorization_token, $x_idempotency_key = null)
    {
        list($response) = $this->postInternationalLabelWithHttpInfo($body, $x_payment_authorization_token, $x_idempotency_key);
        return $response;
    }

    /**
     * Operation postInternationalLabelWithHttpInfo
     *
     * Create a international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\InternationalLabelRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $x_idempotency_key A unique UUID that serves as an idempotency key for safe request retries and duplicate charge prevention during label creation. This value must be a randomly generated UUID and unique per customer (CRID) across all label creation requests. When the same idempotency key is resubmitted with an identical request payload, the API will return the existing label without creating a duplicate or charging additional postage. The UUID will be included in the electronic manifest data (Shipping Services File D5 field) sent to Postal systems. (optional)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \USPS\InternationalLabels\Model\InternationalLabelResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function postInternationalLabelWithHttpInfo($body, $x_payment_authorization_token, $x_idempotency_key = null)
    {
        $returnType = '\USPS\InternationalLabels\Model\InternationalLabelResponse';
        $request = $this->postInternationalLabelRequest($body, $x_payment_authorization_token, $x_idempotency_key);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 201:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\InternationalLabelResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 503:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation postInternationalLabelAsync
     *
     * Create a international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\InternationalLabelRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $x_idempotency_key A unique UUID that serves as an idempotency key for safe request retries and duplicate charge prevention during label creation. This value must be a randomly generated UUID and unique per customer (CRID) across all label creation requests. When the same idempotency key is resubmitted with an identical request payload, the API will return the existing label without creating a duplicate or charging additional postage. The UUID will be included in the electronic manifest data (Shipping Services File D5 field) sent to Postal systems. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function postInternationalLabelAsync($body, $x_payment_authorization_token, $x_idempotency_key = null)
    {
        return $this->postInternationalLabelAsyncWithHttpInfo($body, $x_payment_authorization_token, $x_idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation postInternationalLabelAsyncWithHttpInfo
     *
     * Create a international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\InternationalLabelRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $x_idempotency_key A unique UUID that serves as an idempotency key for safe request retries and duplicate charge prevention during label creation. This value must be a randomly generated UUID and unique per customer (CRID) across all label creation requests. When the same idempotency key is resubmitted with an identical request payload, the API will return the existing label without creating a duplicate or charging additional postage. The UUID will be included in the electronic manifest data (Shipping Services File D5 field) sent to Postal systems. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function postInternationalLabelAsyncWithHttpInfo($body, $x_payment_authorization_token, $x_idempotency_key = null)
    {
        $returnType = '\USPS\InternationalLabels\Model\InternationalLabelResponse';
        $request = $this->postInternationalLabelRequest($body, $x_payment_authorization_token, $x_idempotency_key);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'postInternationalLabel'
     *
     * @param  \USPS\InternationalLabels\Model\InternationalLabelRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $x_idempotency_key A unique UUID that serves as an idempotency key for safe request retries and duplicate charge prevention during label creation. This value must be a randomly generated UUID and unique per customer (CRID) across all label creation requests. When the same idempotency key is resubmitted with an identical request payload, the API will return the existing label without creating a duplicate or charging additional postage. The UUID will be included in the electronic manifest data (Shipping Services File D5 field) sent to Postal systems. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function postInternationalLabelRequest($body, $x_payment_authorization_token, $x_idempotency_key = null)
    {
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling postInternationalLabel'
            );
        }
        // verify the required parameter 'x_payment_authorization_token' is set
        if ($x_payment_authorization_token === null || (is_array($x_payment_authorization_token) && count($x_payment_authorization_token) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $x_payment_authorization_token when calling postInternationalLabel'
            );
        }

        $resourcePath = '/international-label';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($x_payment_authorization_token !== null) {
            $headerParams['X-Payment-Authorization-Token'] = ObjectSerializer::toHeaderValue($x_payment_authorization_token);
        }
        // header params
        if ($x_idempotency_key !== null) {
            $headerParams['X-Idempotency-Key'] = ObjectSerializer::toHeaderValue($x_idempotency_key);
        }


        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['multipart/form-data', 'application/json', 'application/xml', 'application/vnd.usps.labels+json', 'application/vnd.usps.labels+xml']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['multipart/form-data', 'application/json', 'application/xml', 'application/vnd.usps.labels+json', 'application/vnd.usps.labels+xml'],
                ['application/json', 'application/xml']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation postLabelReprint
     *
     * Reprint an international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\LabelReprintRequest $body body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $tracking_number The unique tracking number of the label. (required)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \USPS\InternationalLabels\Model\LabelReprintInternationalMultipartResponse
     */
    public function postLabelReprint($body, $x_payment_authorization_token, $tracking_number)
    {
        list($response) = $this->postLabelReprintWithHttpInfo($body, $x_payment_authorization_token, $tracking_number);
        return $response;
    }

    /**
     * Operation postLabelReprintWithHttpInfo
     *
     * Reprint an international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\LabelReprintRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $tracking_number The unique tracking number of the label. (required)
     *
     * @throws \USPS\InternationalLabels\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \USPS\InternationalLabels\Model\LabelReprintInternationalMultipartResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function postLabelReprintWithHttpInfo($body, $x_payment_authorization_token, $tracking_number)
    {
        $returnType = '\USPS\InternationalLabels\Model\LabelReprintInternationalMultipartResponse';
        $request = $this->postLabelReprintRequest($body, $x_payment_authorization_token, $tracking_number);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\LabelReprintInternationalMultipartResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 429:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 503:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\USPS\InternationalLabels\Model\ErrorMessage',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation postLabelReprintAsync
     *
     * Reprint an international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\LabelReprintRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $tracking_number The unique tracking number of the label. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function postLabelReprintAsync($body, $x_payment_authorization_token, $tracking_number)
    {
        return $this->postLabelReprintAsyncWithHttpInfo($body, $x_payment_authorization_token, $tracking_number)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation postLabelReprintAsyncWithHttpInfo
     *
     * Reprint an international shipping label
     *
     * @param  \USPS\InternationalLabels\Model\LabelReprintRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $tracking_number The unique tracking number of the label. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function postLabelReprintAsyncWithHttpInfo($body, $x_payment_authorization_token, $tracking_number)
    {
        $returnType = '\USPS\InternationalLabels\Model\LabelReprintInternationalMultipartResponse';
        $request = $this->postLabelReprintRequest($body, $x_payment_authorization_token, $tracking_number);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'postLabelReprint'
     *
     * @param  \USPS\InternationalLabels\Model\LabelReprintRequest $body (required)
     * @param  string $x_payment_authorization_token Payment Authorization Token from the payments API Call. (required)
     * @param  string $tracking_number The unique tracking number of the label. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function postLabelReprintRequest($body, $x_payment_authorization_token, $tracking_number)
    {
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling postLabelReprint'
            );
        }
        // verify the required parameter 'x_payment_authorization_token' is set
        if ($x_payment_authorization_token === null || (is_array($x_payment_authorization_token) && count($x_payment_authorization_token) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $x_payment_authorization_token when calling postLabelReprint'
            );
        }
        // verify the required parameter 'tracking_number' is set
        if ($tracking_number === null || (is_array($tracking_number) && count($tracking_number) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_number when calling postLabelReprint'
            );
        }

        $resourcePath = '/international-label-reprint/{trackingNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // header params
        if ($x_payment_authorization_token !== null) {
            $headerParams['X-Payment-Authorization-Token'] = ObjectSerializer::toHeaderValue($x_payment_authorization_token);
        }

        // path params
        if ($tracking_number !== null) {
            $resourcePath = str_replace(
                '{' . 'trackingNumber' . '}',
                ObjectSerializer::toPathValue($tracking_number),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['multipart/form-data', 'application/vnd.usps.labels+json', 'application/vnd.usps.labels+xml', 'application/json', 'application/xml']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['multipart/form-data', 'application/vnd.usps.labels+json', 'application/vnd.usps.labels+xml', 'application/json', 'application/xml'],
                ['application/json', 'application/xml']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option
     *
     * @throws \RuntimeException on file opening failure
     * @return array of http client options
     */
    protected function createHttpClientOption()
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile());
            }
        }

        return $options;
    }
}
