<?php

/**
 * This file defines the message metadata class.
 *
 * @package CGMessageQuery
 * @category async
 * @author calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2015 by Robert Campbell
 */
namespace CGMessageQueue;

/**
 * This class is a wrapper around a message object that allows managing a message within the database, and retrieving extraneous information.
 *
 * @package CGMessageQuery
 * @category async
 * @author calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2015 by Robert Campbell
 */
class MessageMetadata
{
    /**
     * @ignore
     */
    private $_data = array('id'=>null,'queue'=>null,'module'=>null,'data'=>null,'created'=>null,'expires'=>null);

    /**
     * Construct a new metadata object.
     *
     * @param MessageBase|assoc $msg Either a MessageBase object or a database row representing a message.
     */
    public function __construct($msg)
    {
        if( $msg instanceof MessageBase ) {
            // build from a message
            $this->_data['queue'] = $msg->get_queue();
            $this->_data['module'] = $msg->get_module();
            $this->_data['data'] = serialize($msg);
            $this->_data['created'] = time();
            $exp = $msg->get_expiry();
            if( $exp > 0 ) $this->_data['expires'] = $this->_data['created'] + $exp * 60;
        }
        else if( is_array($msg) && isset($msg['id']) && isset($msg['queue']) ) {
            // build from a message array (from the database)
            $this->_data['id'] = (int) $msg['id'];
            $this->_data['queue'] = $msg['queue'];
            $this->_data['module'] = $msg['module'];
            $this->_data['created'] = (int) $msg['created'];
            $this->_data['expires'] = (int) $msg['expires'];
            $this->_data['data'] = $msg['data'];
        }
        else {
            throw new \LogicException('Invalid value passed to '.__METHOD__);
        }
    }

    /**
     * @ignore
     */
    public function __get($key)
    {
        switch( $key ) {
        case 'id':
        case 'queue':
        case 'created':
        case 'expires':
        case 'module':
        case 'data':
            return $this->_data[$key];

        case 'message':
            if( $this->data ) {
                $obj = unserialize($this->data);
                return $obj;
            }
            break;

        default:
            throw new \LogicException("$key is not a gettable member of ".__CLASS__);
        }
    }

    /**
     * Save this metadata object (and its message) to the datbase.
     */
    public function save()
    {
        $db = \cge_utils::get_db();
        if( !$this->id ) {
            $sql = 'INSERT INTO '.QueueManager::table_name().' (queue,module,data,created,expires) VALUES (?,?,?,?,?)';
            $db->Execute($sql,array($this->queue,$this->module,$this->data,$this->created,$this->expires));
            $this->_data['id'] = (int) $db->Insert_ID();
        } else {
            $sql = 'UPDATE '.QueueManager::table_name().' SET queue = ?, module = ?, data = ?, created = ?, expires = ? WHERE id = ?';
            $db->Execute($sql,array($this->queue,$this->module,$this->data,$this->created,$this->expires));
        }
    }

    /**
     * Delete from the database the row represented by this object.
     * This method will throw an exception if the object has not already been saved to the databas.
     */
    public function delete()
    {
        if( !$this->id ) throw new \LogicException('Cannot delete a message object that has not yet been saved.');
        $db = \cge_utils::get_db();
        $sql = 'DELETE FROM '.QueueManager::table_name().' WHERE id = ? AND queue = ?';
        $db->Execute($sql,array($this->id,$this->queue));
        $this->_data['id'] = null;
    }
}
