using System;

namespace Fivestops.Oxide
{
    public class CausalityRequest : IDisposable
    {
        private IntPtr m_ipRequest;
        private bool m_bDisposed = false;

        public string Page
        {
            get
            {
                return (CausalityClient.GetUri (m_ipRequest));
            }
        }

        public string Query
        {
            get
            {
                return (CausalityClient.GetQuery (m_ipRequest));
            }
        }

        public string Method
        {
            get
            {
                return (CausalityClient.GetMethod (m_ipRequest));
            }
        }

        public CausalityRequest (IntPtr request)
        {
            if (request == IntPtr.Zero)
            {
                throw (new ArgumentNullException ("request"));
            }

            m_ipRequest = request;
        }

        public string GetVariable (string key)
        {
            return (CausalityClient.GetTransactionVariable (m_ipRequest, key));
        }

        public int ReadEntityBody (byte[] outBuf, int bufLen)
        {
            if (outBuf.Length != bufLen)
            {
                throw (new ApplicationException (
                            "outBuf.Length != bufLen: " + outBuf.Length.ToString() + 
                            " " + bufLen.ToString()));
            }

            return (CausalityClient.ReadEntityBody (m_ipRequest, outBuf, bufLen));
        }

        public bool IsEntireEntityLoaded()
        {
            return (CausalityClient.IsEntireEntityLoaded (m_ipRequest));
        }

        public string GetRequestHeader (string key)
        {
            return (CausalityClient.GetRequestHeader (m_ipRequest, key));
        }

        public void SetResponseHeader (string key, string value)
        {
            CausalityClient.SetResponseHeader (m_ipRequest, key, value);
        }

        public void SetStatus (int status, string description)
        {
            CausalityClient.SetStatus (m_ipRequest, status, description);
        }

        public bool Write (byte[] data, int dataLen)
        {
            return (CausalityClient.WriteData (m_ipRequest, data, dataLen));
        }

        public bool Write (string data)
        {
            return (CausalityClient.WriteString (m_ipRequest, data));
        }

        public bool HeadersSent()
        {
            return (CausalityClient.HeadersSent (m_ipRequest));
        }

        public string GetRemoteIP()
        {
            return (CausalityClient.GetRemoteIP (m_ipRequest));
        }

        public void Finish()
        {
            this.Dispose (true);

            GC.SuppressFinalize (this);
        }

        public void Dispose()
        {
            this.Dispose (true);

            GC.SuppressFinalize (this);
        }

        private void Dispose (bool disposing)
        {
            if (m_bDisposed == false)
            {
                if (disposing)
                {
                    // release managed components
                }

                CausalityClient.Finish (m_ipRequest);

                m_ipRequest = IntPtr.Zero;

                m_bDisposed = true;
            }
        }

        ~CausalityRequest()
        {
            Dispose (false);
        }
    }
}
