<?php
/********************************************************************************
 * (c)1337 aheadware.com - All rights reserved
 ********************************************************************************/


class Francis_Utils_PushIOS {

    const ENV_SANDBOX = 'sandbox';
    const ENV_PRODUCTION = 'production';

    // Production
    private static $prodApnsHost = 'gateway.sandbox.push.apple.com';
    private static $prodApnsPort = 2195;
    //private static $prodApnsCert = 'FebruarTBuddyAPNBundle.pem';
    //private static $prodApnsCert = 'push060317cert.pem';
    private static $prodApnsCert = 'push270318.pem';

    // Sandbox
    private static $devApnsHost = 'gateway.sandbox.push.apple.com';
    private static $devApnsPort = 2195;
    private static $devApnsCert = NULL;

    // In use
    private static $apnsHost = NULL;
    private static $apnsPort = 2195;
    private static $apnsCert = NULL;

    /**
     * @param string $env
     */
    public function __construct( $env = self::ENV_PRODUCTION ) {
        if ( self::ENV_PRODUCTION === $env ) {
            self::$apnsHost = 'gateway.push.apple.com';
            self::$apnsCert = Francis_Utils_Config::get( 'path.root' ) . '/data/' . self::$prodApnsCert;
        } else {
            throw new Exception( "Sandbox mode not supported." );
            self::$apnsHost = 'gateway.sandbox.push.apple.com';
            self::$apnsCert = self::$devApnsCert;
        }
    }

    /**
     *
     * @param array $deviceIds
     * @param array $message ( 'title' => string, 'message' => string )
     */
    public function send( array $deviceIds, array $message ) {

        // Init
        $error = '';
        $errorString = '';
        $isError = false;
        $alert = is_array( $message ) && isset( $message[ 'title' ] ) ? $message[ 'title' ] : NULL;

        if ( is_null( $alert ) || 0 === count( $deviceIds ) ) return;

        // Payload erstellen und JSON codieren
        $payload['aps'] = array('alert' => $alert, 'badge' => 0, 'sound' => 'default');
        $payload = json_encode($payload);

        try {
            $streamContext = stream_context_create();
            stream_context_set_option( $streamContext, 'ssl', 'local_cert', self::$apnsCert );
            $apns = stream_socket_client(
                'ssl://' . self::$apnsHost. ':' . self::$apnsPort,
                $error,
                $errorString,
                2,
                STREAM_CLIENT_CONNECT,
                $streamContext
            );
            // Connetion etablished
            if ($apns)
            {
                foreach( $deviceIds as $deviceToken ) {
                    // Send message
                    $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $deviceToken)) . chr(0) . chr(strlen($payload)) . $payload;
                }

                fwrite($apns, $apnsMessage);

                // Verbindung schliessen
                fclose($apns);
            }
            else
            {
                $isError = true;
            }

        } catch ( Exception $e ) {
            $isError = true;
            $error = 500;
            $errorString = $e->getMessage();
        }

        if ( $isError ) {
            TB_Server_Utils_Log::get()->log( $error . ' - ' . $errorString );
        }

    }

}