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

/**
 * Class Francis_Utils_Push_Google
 */
class Francis_Utils_PushGoogle {

    const API_URL = 'https://android.googleapis.com/gcm/send';

    static protected $instance = NULL;

    protected $apiKey = NULL;
    private function __construct() {}
    private function __clone() {}

    /**
     * @param array $cfg
     * @return Francis_Utils_Push_Google|null
     */
    static public function get( array $cfg ) {
        if ( is_null( self::$instance ) ) {
            self::$instance = new self();
            self::$instance->apiKey = isset( $cfg[ 'api_key' ] ) ? $cfg[ 'api_key' ] : NULL;
        }
        return self::$instance;
    }

    /**
     * Send push notification to the Google Messaging Cloud
     *
     * @param array $regIds
     * @param array $msg
     *
     * @return string   The transfer protocol (ie. a JSON string)
     */
    public function send( array $regIds, array $msgBundle ) {
        // Validations
        if ( 0 === count( $regIds ) ) {
            // Nothing to send
            return;
        }
        if ( !isset( $msgBundle['message' ] ) || !isset( $msgBundle['title' ] ) ) {
            throw new Exception( 'Message bundle must at least contain a title and a message.' );
        }

        // prep the bundle
        $msg = array (
            'message' 	=> $msgBundle[ 'message' ],
            'title'		=> $msgBundle[ 'title' ],
            'subtitle'	=> isset( $msgBundle[ 'subtitle'] ) ? $msgBundle[ 'subtitle'] : NULL,
            'tickerText'=> isset( $msgBundle[ 'tickerText' ] ) ? $msgBundle[ 'tickerText' ] : NULL,
            'vibrate'	=> 1,   // Default for now
            'sound'		=> 0,   // Default for now
            'largeIcon'	=> 'large_icon',
            'smallIcon'	=> 'small_icon'
        );

        $fields = array (
            'registration_ids' => array_unique( $regIds ),
            'data' => $msg
        );

        $headers = array (
            'Authorization: key=' . $this->apiKey,
            'Content-Type: application/json'
        );

        $ch = curl_init();
        curl_setopt( $ch,CURLOPT_URL, self::API_URL );
        curl_setopt( $ch,CURLOPT_POST, true );
        curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
        curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
        $result = curl_exec($ch );
        curl_close( $ch );

        return $result;
    }

    /**
     * Get error from given string
     *
     * Note:
     * Experimental - it's not safe to use this method. Only for debugging purposes.
     *
     * @param string $result    Result json string
     *
     * @return NULL | string    NULL means no error, else error as a string
     */
    static public function getErrorFromResult( $result ) {
        // Default error
        $err = 'Unknown : ' . strip_tags( $result );

        // Try to resolve result
        $res = json_decode( '' . $result, true );
        if ( is_array( $res ) && isset( $res[ 'success' ] ) && 1 == $res[ 'success' ] ) {
            $err = NULL;
        } else if ( is_array( $res ) && isset( $res[ 'failure' ] ) && 1 == $res[ 'failure' ] ) {
            $err = 'Failure';
            if ( isset( $res[ 'results' ] ) && is_array( $res[ 'results' ] ) ) {
                $err .= ' : ' . json_encode( $res[ 'results' ] );
            }
        }

        return $err;
    }
}