<?php

/**
 * This file defines the abstract MessageBase class.
 *
 * @package CGMessageQuery
 * @category async
 * @author calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2015 by Robert Campbell
 */

namespace CGMessageQueue;

/**
 * An abstract class for creating a message.
 *
 * @package CGMessageQuery
 * @category async
 * @author calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2015 by Robert Campbell
 */
abstract class MessageBase
{
    /**
     * @ignore
     */
    private $_name;

    /**
     * @ignore
     */
    private $_queue;

    /**
     * @ignore
     */
    private $_module;

    /**
     * @ignore
     */
    private $_expiry;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->set_name(basename(__CLASS__));
    }

    /**
     * Get the name of this message object.
     * By default it returns the class name.
     *
     * @return string
     */
    public function get_name() { return $this->_name; }

    /**
     * Set the name of this message object.
     *
     * @param string $str
     */
    public function set_name($str)
    {
        $str = trim($str);
        if( !$str ) throw new \LogicException('Empty string passed to '.__METHOD__);
        $this->_name = $str;
    }

    /**
     * Get the name of the queue that this message object is to be placed in.
     * There is no default value for the queue name, but one is required before sending the message.
     *
     * @return string.
     */
    public function get_queue() { return $this->_queue; }

    /**
     * Set the queue name.
     *
     * @param string $str
     */
    public function set_queue($str)
    {
        $str = trim($str);
        if( !$str ) throw new \LogicException('Empty string passed to '.__METHOD__);
        $this->_queue = $str;
    }

    /**
     * Get the name of the module that is sending this message.
     * There is no default value for the module name, however one must be set before sending the message.
     *
     * @return strung
     */
    public function get_module() { return $this->_module; }

    /**
     * Set the module name for this message.
     *
     * @param string $str
     */
    public function set_module($str)
    {
        $str = trim($str);
        if( !$str ) throw new \LogicException('Empty string passed to '.__METHOD__);
        $this->_module = $str;
    }

    /**
     * Get the expiry time (in minutes) for this message.
     *
     * return int
     */
    public function get_expiry() { return $this->_expiry; }

    /**
     * Set the expiry time (in minutes) for this message.
     *
     * @param int|null $val  An integer value, or null may be specified.
     */
    public function set_expiry($val)
    {
        if( is_null($val) ) {
            $this->_expiry = $val;
        }
        else {
            $this->_expiry = max(1,min(24*60,(int)$val)); // between 1 minute and 24 hours.
        }
    }

    /**
     * Test if this message is minimally valid, and can be sent.
     *
     * @return bool
     */
    public function is_valid()
    {
        if( !$this->_name || !$this->_queue || !$this->_module ) return FALSE;
        return TRUE;
    }

    /**
     * An abstract method to handle this message once it is popped off of the queue.
     * All processing should be done from within this method.
     *
     * This method is called by the asynchronous process handler.
     *
     * @return void
     */
    abstract public function handle();

    /**
     * Place this message intot he queue for asynchrnous processing.
     * This method throws an exception if the message is not valid.
     *
     * @return void
     */
    public function send()
    {
        if( !$this->is_valid() ) throw new \LogicException('Attempt to save an invalid message');
        QueueManager::get_instance()->send($this);
    }
}
