<?php

/**

 * 2007-2014 [PagSeguro Internet Ltda.]

 *

 * NOTICE OF LICENSE

 *

 *Licensed under the Apache License, Version 2.0 (the "License");

 *you may not use this file except in compliance with the License.

 *You may obtain a copy of the License at

 *

 *http://www.apache.org/licenses/LICENSE-2.0

 *

 *Unless required by applicable law or agreed to in writing, software

 *distributed under the License is distributed on an "AS IS" BASIS,

 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 *See the License for the specific language governing permissions and

 *limitations under the License.

 *

 *  @author    André da Silva Medeiros <andre@swdesign.net.br>

 *  @copyright 2007-2014 PagSeguro Internet Ltda.

 *  @license   http://www.apache.org/licenses/LICENSE-2.0

 */



/***

 * Encapsulates web service calls regarding PagSeguro payment requests

 */

class PagSeguroPreApprovalSearchService

{



    /***

     *

     */

    const SERVICE_NAME = 'preApproval';

    /**

     * @var

     */

    private static $service;

    /**

     * @var

     */

    private static $connectionData;



    /***

     * @param PagSeguroConnectionData $connectionData

     * @param $notificationCode

     * @return string

     */

    private static function buildFindByNotificationUrl(PagSeguroConnectionData $connectionData, $notificationCode)

    {

        $url = $connectionData->getWebserviceUrl() . $connectionData->getResource('findUrl') . 'notifications';

        return "{$url}/{$notificationCode}/?" . $connectionData->getCredentialsUrlQuery();

    }



    /***

     * @param PagSeguroConnectionData $connectionData

     * @param $code

     * @return string

     */

    private static function buildFindByCodeUrl(PagSeguroConnectionData $connectionData, $code)

    {

        $url = $connectionData->getWebserviceUrl() . $connectionData->getResource('findUrl');

        return "{$url}{$code}/?" . $connectionData->getCredentialsUrlQuery();

    }



    /***

     * @param PagSeguroConnectionData $connectionData

     * @param $code

     * @return string

     */

    private static function buildFindByDayIntervalUrl(PagSeguroConnectionData $connectionData, $interval)

    {

        $url = $connectionData->getWebserviceUrl() . $connectionData->getResource('findUrl') . 'notifications';

        return "{$url}?" . $connectionData->getCredentialsUrlQuery() . "&interval=" . $interval;

    }



    /**

     * @param PagSeguroConnectionData $connectionData

     * @param array $params

     * @return string

     */

    private static function buildFindByDateIntervalUrl(PagSeguroConnectionData $connectionData, array $params)

    {

        $url = $connectionData->getWebserviceUrl() . $connectionData->getResource('findUrl');

        $initialDate = $params['initialDate'] != null ? $params['initialDate'] : "";

        $finalDate = $params['finalDate'] != null ? ("&finalDate=" . $params['finalDate']) : "";



        if ($params['pageNumber'] != null) {

            $page = "&page=" . $params['pageNumber'];

        }

        if ($params['maxPageResults'] != null) {

            $maxPageResults = "&maxPageResults=" . $params['maxPageResults'];

        }



        return "{$url}?" . $connectionData->getCredentialsUrlQuery() . "&initialDate={$initialDate}{$finalDate}

            {$page}{$maxPageResults}";

    }



    /**

     * @param PagSeguroConnectionData $connectionData

     * @param array $params

     * @return string

     */

    private static function buildFindByReferenceUrl(PagSeguroConnectionData $connectionData, array $params)

    {

        $url = $connectionData->getWebserviceUrl() . $connectionData->getResource('findUrl');

        $initialDate = $params['initialDate'] != null ? $params['initialDate'] : "";

        $finalDate = $params['finalDate'] != null ? ("&finalDate=" . $params['finalDate']) : "";



        $reference = $params['reference'] != null ? ("&reference=" . $params['reference']) : "";



        if ($params['pageNumber'] != null) {

            $page = "&page=" . $params['pageNumber'];

        }

        if ($params['maxPageResults'] != null) {

            $maxPageResults = "&maxPageResults=" . $params['maxPageResults'];

        }



        return "{$url}?" . $connectionData->getCredentialsUrlQuery()

            . "&initialDate={$initialDate}{$finalDate}{$page}{$maxPageResults}{$reference}";

    }



    /**

     * @param $pageNumber

     * @param $maxPageResults

     * @param $initialDate

     * @param null $finalDate

     * @return array

     */

    private function buildParams($pageNumber, $maxPageResults, $initialDate, $finalDate = null, $reference = null)

    {

        $params = array(

            'initialDate' => PagSeguroHelper::formatDate($initialDate),

            'pageNumber' => $pageNumber,

            'maxPageResults' => $maxPageResults

        );



        $params['finalDate'] = $finalDate ? PagSeguroHelper::formatDate($finalDate) : null;



        $params['reference'] = $reference ? PagSeguroHelper::formatDate($reference) : null;



        return $params;

    }



    /**

     * @param PagSeguroCredentials $credentials

     * @param $code

     * @return null|PagSeguroParserData

     * @throws Exception

     * @throws PagSeguroServiceException

     */

    public static function searchByCode(PagSeguroCredentials $credentials, $code)

    {



        LogPagSeguro::info("PagSeguroPreApprovalService.FindByCode($code) - begin");

        self::$connectionData = new PagSeguroConnectionData($credentials, self::SERVICE_NAME);



        try {

            $connection = new PagSeguroHttpConnection();

            $connection->get(

                self::buildFindByCodeUrl(self::$connectionData, $code),

                self::$connectionData->getServiceTimeout(),

                self::$connectionData->getCharset()

            );

            self::$service = "FindByCode";

            return self::getResult($connection, $code);



        } catch (PagSeguroServiceException $err) {

            //Logging

            LogPagSeguro::error("PagSeguroServiceException: " . $err->getMessage());

            //Exception

            throw $err;



        } catch (Exception $err) {

            //Logging

            LogPagSeguro::error("Exception: " . $err->getMessage());

            //Exception

            throw $err;

        }

    }



    /**

     * @param PagSeguroCredentials $credentials

     * @param $interval

     * @return null|PagSeguroParserData

     * @throws Exception

     * @throws PagSeguroServiceException

     */

    public static function searchByInterval(PagSeguroCredentials $credentials, $interval)

    {



        LogPagSeguro::info("PagSeguroPreApprovalService.FindByDayInterval($interval) - begin");

        self::$connectionData = new PagSeguroConnectionData($credentials, self::SERVICE_NAME);



        try {

            $connection = new PagSeguroHttpConnection();

            $connection->get(

                self::buildFindByDayIntervalUrl(self::$connectionData, $interval),

                self::$connectionData->getServiceTimeout(),

                self::$connectionData->getCharset()

            );

            self::$service = "FindByDayInterval";

            return self::getResult($connection);



        } catch (PagSeguroServiceException $err) {

            //Logging

            LogPagSeguro::error("PagSeguroServiceException: " . $err->getMessage());

            //Exception

            throw $err;



        } catch (Exception $err) {

            //Logging

            LogPagSeguro::error("Exception: " . $err->getMessage());

            //Exception

            throw $err;

        }

    }



    /**

     * @param PagSeguroCredentials $credentials

     * @param $pageNumber

     * @param $maxPageResults

     * @param $initialDate

     * @param null $finalDate

     * @return null|PagSeguroParserData

     * @throws Exception

     * @throws PagSeguroServiceException

     */

    public static function searchByDate(

        PagSeguroCredentials $credentials,

        $pageNumber,

        $maxPageResults,

        $initialDate,

        $finalDate = null

    ) {

        //Logging

        $log['text'] = "PagSeguroPreApprovalService.FindByDateInterval(initialDate="

            . PagSeguroHelper::formatDate($initialDate) . ", finalDate=" . PagSeguroHelper::formatDate($finalDate) .

            "begin";

        LogPagSeguro::info($log['text']);



        self::$connectionData = new PagSeguroConnectionData($credentials, self::SERVICE_NAME);



        $params = self::buildParams($pageNumber, $maxPageResults, $initialDate, $finalDate);



        try {

            $connection = new PagSeguroHttpConnection();

            $connection->get(

                self::buildFindByDateIntervalUrl(self::$connectionData, $params),

                self::$connectionData->getServiceTimeout(),

                self::$connectionData->getCharset()

            );

            self::$service = "FindByDateInterval";

            return self::getResult($connection);



        } catch (PagSeguroServiceException $err) {

            //Logging

            LogPagSeguro::error("PagSeguroServiceException: " . $err->getMessage());

            //Exception

            throw $err;



        } catch (Exception $err) {

            //Logging

            LogPagSeguro::error("Exception: " . $err->getMessage());

            //Exception

            throw $err;

        }

    }



    /**

     * @param PagSeguroCredentials $credentials

     * @param $pageNumber

     * @param $maxPageResults

     * @param $initialDate

     * @param null $finalDate

     * @return null|PagSeguroParserData

     * @throws Exception

     * @throws PagSeguroServiceException

     */

    public static function searchByReference(

        PagSeguroCredentials $credentials,

        $pageNumber,

        $maxPageResults,

        $initialDate,

        $finalDate = null,

        $reference

    ) {

        //Logging

        $log['text'] = "PagSeguroPreApprovalService.FindByReference(initialDate="

            . PagSeguroHelper::formatDate($initialDate) . ", finalDate=" . PagSeguroHelper::formatDate($finalDate)

            . ", reference=" . $reference . "begin";

        LogPagSeguro::info($log['text']);



        self::$connectionData = new PagSeguroConnectionData($credentials, self::SERVICE_NAME);



        $params = self::buildParams($pageNumber, $maxPageResults, $initialDate, $finalDate, $reference);



        try {

            $connection = new PagSeguroHttpConnection();

            $connection->get(

                self::buildFindByReferenceUrl(self::$connectionData, $params),

                self::$connectionData->getServiceTimeout(),

                self::$connectionData->getCharset()

            );



            self::$service = "FindByReference";

            return self::getResult($connection);



        } catch (PagSeguroServiceException $err) {

            //Logging

            LogPagSeguro::error("PagSeguroServiceException: " . $err->getMessage());

            //Exception

            throw $err;



        } catch (Exception $err) {

            //Logging

            LogPagSeguro::error("Exception: " . $err->getMessage());

            //Exception

            throw $err;

        }

    }



    /**

     * @param PagSeguroCredentials $credentials

     * @param $notificationCode

     * @return null|PagSeguroParserData

     * @throws Exception

     * @throws PagSeguroServiceException

     */

    public static function findByNotification(PagSeguroCredentials $credentials, $notificationCode)

    {



        LogPagSeguro::info("PagSeguroPreApprovalService.FindByNotification($notificationCode) - begin");

        self::$connectionData = new PagSeguroConnectionData($credentials, self::SERVICE_NAME);



        try {

            $connection = new PagSeguroHttpConnection();

            $connection->get(

                self::buildFindByNotificationUrl(self::$connectionData, $notificationCode),

                self::$connectionData->getServiceTimeout(),

                self::$connectionData->getCharset()

            );

            self::$service = "FindByNotification";

            return self::getResult($connection, $notificationCode);



        } catch (PagSeguroServiceException $err) {

            //Logging

            LogPagSeguro::error("PagSeguroServiceException: " . $err->getMessage());

            //Exception

            throw $err;



        } catch (Exception $err) {

            //Logging

            LogPagSeguro::error("Exception: " . $err->getMessage());

            //Exception

            throw $err;

        }

    }



    /**

     * @param $connection

     * @param null $code

     * @return null|PagSeguroParserData

     * @throws PagSeguroServiceException

     */

    private function getResult($connection, $code = null)

    {



        $httpStatus = new PagSeguroHttpStatus($connection->getStatus());

        $response   = $connection->getResponse();



        switch ($httpStatus->getType()) {

            case 'OK':

                switch(self::$service) {

                    case "FindByCode":

                        $result = PagSeguroPreApprovalParser::readPreApproval($response);

                        break;

                    case "FindByNotification":

                        $result = PagSeguroPreApprovalParser::readPreApproval($response);

                        break;

                    case "FindByDayInterval":

                        $result = PagSeguroPreApprovalParser::readSearchResult($response);

                        break;

                    case "FindByDateInterval":

                        $result = PagSeguroPreApprovalParser::readSearchResult($response);

                        break;

                    case "FindByReference":

                        $result = PagSeguroPreApprovalParser::readSearchResult($response);

                        break;

                }



                //Logging

                if (is_null($code) && self::$service == "PreApprovalRequest") {

                    $log['text'] = sprintf(

                        "PagSeguroPreApprovalService.%s(".$response->toString().") - end ",

                        self::$service

                    );

                    LogPagSeguro::info($log['text'] . ")");

                } else {

                    $log['text'] = sprintf("PagSeguroPreApprovalService.%s($code) - end ", self::$service);

                    LogPagSeguro::info($log['text']);

                }



                break;

            case 'BAD_REQUEST':



                $errors = PagSeguroServiceParser::readErrors($response);

                $errors = new PagSeguroServiceException($httpStatus, $errors);



                //Logging

                $log['text']  = sprintf("PagSeguroPreApprovalService.%s($code) - error ", self::$service);

                LogPagSeguro::error($log['text'] . $errors->getOneLineMessage());



                //Exception

                throw $errors;



                break;

            default:



                $errors = new PagSeguroServiceException($httpStatus);



                //Logging

                $log['text'] = sprintf("PagSeguroPreApprovalService.%s($code) - error ", self::$service);

                LogPagSeguro::error($log['text'] . $errors->getOneLineMessage());



                //Exception

                throw $errors;



                break;

        }

        return isset($result) ? $result : null;

    }

}

