/* Copyright (c) 2008-2011 - Eric P. Mangold
 * Released under the terms of the MIT/X11 license - see LICENSE.txt */
using System;

namespace AMP
{
    /// <summary>
    /// This is the most brain-dead, simple abstraction for a deferred result possible.
    /// Inside your AMP Command responder method you may return one of these,
    /// instead of returning an AMP.Msg. Then later, when the result you wish to return
    /// to the caller of your Command is ready, you will call respond(AMP.Msg) on the
    /// DeferredResponse you returned earlier.
    /// 
    /// If an error occurred producing the result you should call respond() and pass it
    /// an Exception object, instead of an AMP.Msg.
    /// If the type of the Exception object has been registered on the Command that was 
    /// invoked (with Command.AddError(...)) then the appropriate AMP error code will
    /// be sent on the wire, otherwise the generic error code will be used.
    /// </summary>
    public class DeferredResponse
    {
        public delegate void Delegate(Object AmpMessageOrException);

        private DeferredResponse.Delegate theCallback;
        private Object savedResult;
        internal void setCallback(DeferredResponse.Delegate callback)
        {
            if (savedResult != null)
            {
                // run callback synchronously
                callback(savedResult);
            }
            else
            {
                theCallback = callback;
            }
        }
        public void respond(Object result)
        {
            if (theCallback == null)
            {
                savedResult = result;
            }
            else
            {
                theCallback(result);
            }
        }
    }
}
