<?php

/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Gdata
 * @subpackage Health
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Health.php 18951 2009-11-12 16:26:19Z alexander $
 */

/**
 * @see Zend_Gdata
 */
require_once 'Zend/Gdata.php';

/**
 * @see Zend_Gdata_Health_ProfileFeed
 */
require_once 'Zend/Gdata/Health/ProfileFeed.php';

/**
 * @see Zend_Gdata_Health_ProfileListFeed
 */
require_once 'Zend/Gdata/Health/ProfileListFeed.php';

/**
 * @see Zend_Gdata_Health_ProfileListEntry
 */
require_once 'Zend/Gdata/Health/ProfileListEntry.php';

/**
 * @see Zend_Gdata_Health_ProfileEntry
 */
require_once 'Zend/Gdata/Health/ProfileEntry.php';

/**
 * Service class for interacting with the Google Health Data API
 *
 * @link http://code.google.com/apis/health
 *
 * @category   Zend
 * @package    Zend_Gdata
 * @subpackage Health
 * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Gdata_Health extends Zend_Gdata
{
    /**
     * URIs of the AuthSub/OAuth feeds.
     */
    const AUTHSUB_PROFILE_FEED_URI =
        'https://www.google.com/health/feeds/profile/default';
    const AUTHSUB_REGISTER_FEED_URI =
        'https://www.google.com/health/feeds/register/default';

    /**
     * URIs of the ClientLogin feeds.
     */
    const CLIENTLOGIN_PROFILELIST_FEED_URI =
        'https://www.google.com/health/feeds/profile/list';
    const CLIENTLOGIN_PROFILE_FEED_URI =
        'https://www.google.com/health/feeds/profile/ui';
    const CLIENTLOGIN_REGISTER_FEED_URI =
        'https://www.google.com/health/feeds/register/ui';

    /**
     * Authentication service names for Google Health and the H9 Sandbox.
     */
    const HEALTH_SERVICE_NAME = 'health';
    const H9_SANDBOX_SERVICE_NAME = 'weaver';

    /**
     * Profile ID used for all API interactions.  This can only be set when
     * using ClientLogin for authentication.
     *
     * @var string
     */
    private $_profileID = null;

    /**
     * True if API calls should be made to the H9 developer sandbox at /h9
     * rather than /health
     *
     * @var bool
     */
    private $_useH9Sandbox = false;

    public static $namespaces =
        array('ccr' => 'urn:astm-org:CCR',
              'batch' => 'http://schemas.google.com/gdata/batch',
              'h9m' => 'http://schemas.google.com/health/metadata',
              'gAcl' => 'http://schemas.google.com/acl/2007',
              'gd' => 'http://schemas.google.com/g/2005');

    /**
     * Create Zend_Gdata_Health object
     *
     * @param Zend_Http_Client $client (optional) The HTTP client to use when
     *     when communicating with the Google Health servers.
     * @param string $applicationId The identity of the application in the form
     *     of Company-AppName-Version
     * @param bool $useH9Sandbox True if the H9 Developer's Sandbox should be
     *     used instead of production Google Health.
     */
    public function __construct($client = null, $applicationId = 'MyCompany-MyApp-1.0', $useH9Sandbox = false)
    {
        $this->registerPackage('Zend_Gdata_Health');
        $this->registerPackage('Zend_Gdata_Health_Extension_Ccr');
        parent::__construct($client, $applicationId);
        $this->_useH9Sandbox = $useH9Sandbox;
    }

    /**
     * Gets the id of the user's profile
     *
     * @return string The profile id
     */
    public function getProfileID()
    {
        return $this->_profileID;
    }

    /**
     * Sets which of the user's profiles will be used
     *
     * @param string $id The profile ID
     * @return Zend_Gdata_Health Provides a fluent interface
     */
    public function setProfileID($id) {
        $this->_profileID = $id;
        return $this;
    }

     /**
     * Retrieves the list of profiles associated with the user's ClientLogin
     * credentials.
     *
     * @param string $query The query of the feed as a URL or Query object
     * @return Zend_Gdata_Feed
     */
    public function getHealthProfileListFeed($query = null)
    {
        if ($this->_httpClient->getClientLoginToken() === null) {
            require_once 'Zend/Gdata/App/AuthException.php';
            throw new Zend_Gdata_App_AuthException(
                'Profiles list feed is only available when using ClientLogin');
        }

        if($query === null)  {
            $uri = self::CLIENTLOGIN_PROFILELIST_FEED_URI;
        } else if ($query instanceof Zend_Gdata_Query) {
            $uri = $query->getQueryUrl();
        } else {
            $uri = $query;
        }

        // use correct feed for /h9 or /health
        if ($this->_useH9Sandbox) {
            $uri = preg_replace('/\/health\//', '/h9/', $uri);
        }

        return parent::getFeed($uri, 'Zend_Gdata_Health_ProfileListFeed');
    }

    /**
     * Retrieve a user's profile as a feed object.  If ClientLogin is used, the
     * profile associated with $this->_profileID is returned, otherwise
     * the profile associated with the AuthSub token is read.
     *
     * @param mixed $query The query for the feed, as a URL or Query
     * @return Zend_Gdata_Health_ProfileFeed
     */
    public function getHealthProfileFeed($query = null)
    {
        if ($this->_httpClient->getClientLoginToken() !== null &&
            $this->getProfileID() == null) {
            require_once 'Zend/Gdata/App/AuthException.php';
            throw new Zend_Gdata_App_AuthException(
                'Profile ID must not be null. Did you call setProfileID()?');
        }

        if ($query instanceof Zend_Gdata_Query) {
            $uri = $query->getQueryUrl();
        } else if ($this->_httpClient->getClientLoginToken() !== null &&
                   $query == null) {
            $uri = self::CLIENTLOGIN_PROFILE_FEED_URI . '/' . $this->getProfileID();
        } else if ($query === null) {
            $uri = self::AUTHSUB_PROFILE_FEED_URI;
        } else {
            $uri = $query;
        }

        // use correct feed for /h9 or /health
        if ($this->_useH9Sandbox) {
            $uri = preg_replace('/\/health\//', '/h9/', $uri);
        }

        return parent::getFeed($uri, 'Zend_Gdata_Health_ProfileFeed');
    }

    /**
     * Retrieve a profile entry object
     *
     * @param mixed $query The query for the feed, as a URL or Query
     * @return Zend_Gdata_Health_ProfileEntry
     */
    public function getHealthProfileEntry($query = null)
    {
        if ($query === null) {
            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
            throw new Zend_Gdata_App_InvalidArgumentException(
                'Query must not be null');
        } else if ($query instanceof Zend_Gdata_Query) {
            $uri = $query->getQueryUrl();
        } else {
            $uri = $query;
        }
        return parent::getEntry($uri, 'Zend_Gdata_Health_ProfileEntry');
    }

    /**
     * Posts a new notice using the register feed.  This function constructs
     * the atom profile entry.
     *
     * @param string $subject The subject line of the notice
     * @param string $body The message body of the notice
     * @param string $bodyType The (optional) type of message body
     *     (text, xhtml, html, etc.)
     * @param string $ccrXML The (optional) CCR to add to the user's profile
     * @return Zend_Gdata_Health_ProfileEntry
     */
    public function sendHealthNotice($subject, $body, $bodyType = null, $ccrXML = null)
    {
        if ($this->_httpClient->getClientLoginToken()) {
            $profileID = $this->getProfileID();
            if ($profileID !== null) {
                $uri = self::CLIENTLOGIN_REGISTER_FEED_URI . '/' . $profileID;
            } else {
                require_once 'Zend/Gdata/App/AuthException.php';
                throw new Zend_Gdata_App_AuthException(
                    'Profile ID must not be null. Did you call setProfileID()?');
            }
        } else {
            $uri = self::AUTHSUB_REGISTER_FEED_URI;
        }

        $entry = new Zend_Gdata_Health_ProfileEntry();
        $entry->title = $this->newTitle($subject);
        $entry->content = $this->newContent($body);
        $entry->content->type = $bodyType ? $bodyType : 'text';
        $entry->setCcr($ccrXML);

        // use correct feed for /h9 or /health
        if ($this->_useH9Sandbox) {
            $uri = preg_replace('/\/health\//', '/h9/', $uri);
        }

        return $this->insertEntry($entry, $uri, 'Zend_Gdata_Health_ProfileEntry');
    }
}
