<?php
/**
 * YANA library
 *
 * Software:  Yana PHP-Framework
 * Version:   {VERSION} - {DATE}
 * License:   GNU GPL  http://www.gnu.org/licenses/
 *
 * This program: can be redistributed and/or modified under the
 * terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 *
 * This notice MAY NOT be removed.
 *
 * @package  yana
 * @license  http://www.gnu.org/licenses/gpl.txt
 */

/**
 * <<abstract>> Report
 *
 * This is an abstract super class for all kinds of messages.
 *
 * @abstract
 * @access      public
 * @package     yana
 * @subpackage  error_reporting
 */
abstract class Report extends Exception
{
    /**
     * Message queue
     *
     * @access  protected
     * @static
     * @var     array
     * @ignore
     */
    protected static $queue = array();

    /**
     * context data
     *
     * Any kind of data that might help to understand the context
     * in which the message was created.
     *
     * @access  protected
     * @var     mixed
     * @ignore
     */
    protected $data = null;

    /**
     * constructor
     *
     * Create a new instance, representing a system message.
     *
     * @param  string  $message  the message that should be reported
     * @param  int     $code     optional error code
     * @param  mixed   $data     any kind of data that might help to understand context
     *                           in which the message was created
     */
    public function __construct($message = "", $code = E_USER_NOTICE, $data = null)
    {
        if (!empty($message)) {
            assert('is_string($message); // Wrong argument type for argument 1, String expected');
            assert('is_int($code); // Wrong argument type for argument 2, Integer expected');

            if (is_array($data)) {
                $newMessage = SmartUtility::replaceToken("$message", $data);
                if ($newMessage !== $message) {
                    $data = null;
                }
                $message = $newMessage;
                unset($newMessage);
                $message = Language::getInstance()->replaceToken($message);
            }
            $this->setData($data);

            // add to message queue
            assert('is_array(self::$queue); // Static member "queue" is expected to be an array.');
            self::$queue[] = $this;
        }

        parent::__construct($message, $code);
    }

    /**
     * get list of messages
     *
     * Returns the message queue as an array of objets of type Message.
     * The list is sorted in order of creation of the messages.
     *
     * @access  public
     * @static
     * @return  array
     */
    public static function getMessages()
    {
        assert('is_array(self::$queue); // Static member "queue" is expected to be an array.');
        return self::$queue;
    }

    /**
     * get number of messages
     *
     * Returns the number of messages in the message queue.
     * If the queue is empty, 0 is returned.
     *
     * @access  public
     * @static
     * @return  int
     */
    public static function countMessages()
    {
        assert('is_array(self::$queue); // Static member "queue" is expected to be an array.');
        return count(self::$queue);
    }

    /**
     * get context data
     *
     * Returns given context data (where available).
     *
     * @access  public
     * @final
     * @return  mixed
     */
    final public function getData()
    {
        return $this->data;
    }

    /**
     * set context data
     *
     * @access  protected
     * @param   mixed  $data    context data
     * @ignore
     */
    protected function setData($data)
    {
        $this->data = $data;
    }

    /**
     * returns the message string of this event
     *
     * This creates a string of at most 1000 characters
     * containing the text in the message attribute and a serialized
     * representation of the data attribute.
     *
     * @access public
     * @return string
     */
    public function __toString()
    {
        $message = $this->message;
        if (!empty($this->data)) {
            if (is_scalar($this->data)) {
                $message .= ";".$this->data;
            } elseif (is_array($this->data)) {
                $message .= ";".str_replace("\n", '', SML::encode($this->data));
            } else {
                $message .= ";".print_r($this->data, true);
            }
        }
        $message = preg_replace('/\s/', ' ', $message);
        $message = mb_substr($message, 0, 1000);
        $message = str_replace('"', '&quot;', $message);
        return $message;
    }
}

?>