/*
 * TestContext.cs --
 *
 * Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: $
 */

using System;
using Eagle._Attributes;
using Eagle._Components.Public;
using Eagle._Containers.Public;
using Eagle._Interfaces.Private;

namespace Eagle._Components.Private
{
    [ObjectId("935c117f-fba9-4dd6-b3a5-ff2ea4240a10")]
    internal sealed class TestContext : ITestContext, IDisposable
    {
        #region Public Constructors
        public TestContext(int threadId)
        {
            this.threadId = threadId;

            statistics = new int[(int)TestInformationType.SizeOf];
            constraints = new StringList();
            skipped = new StringList();
            failures = new StringList();
            counts = new IntDictionary();
            match = new StringList();
            skip = new StringList();
            returnCodeMessages = TestOps.GetReturnCodeMessages();

            ///////////////////////////////////////////////////////////////////

#if DEBUGGER
            breakpoints = new StringDictionary();
#endif

            path = null;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IThreadContext Members
        public bool Disposed
        {
            get { return disposed; }
        }

        ///////////////////////////////////////////////////////////////////////

        private int threadId;
        public int ThreadId
        {
            get
            {
                //
                // NOTE: *EXEMPT* Hot path.
                //
                // CheckDisposed();

                return threadId;
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region ITestContext Members
        private int[] statistics;
        public int[] Statistics
        {
            get { CheckDisposed(); return statistics; }
            set { CheckDisposed(); statistics = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private StringList constraints;
        public StringList Constraints
        {
            get { CheckDisposed(); return constraints; }
            set { CheckDisposed(); constraints = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private StringList skipped;
        public StringList Skipped
        {
            get { CheckDisposed(); return skipped; }
            set { CheckDisposed(); skipped = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private StringList failures;
        public StringList Failures
        {
            get { CheckDisposed(); return failures; }
            set { CheckDisposed(); failures = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private IntDictionary counts;
        public IntDictionary Counts
        {
            get { CheckDisposed(); return counts; }
            set { CheckDisposed(); counts = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private StringList match;
        public StringList Match
        {
            get { CheckDisposed(); return match; }
            set { CheckDisposed(); match = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private StringList skip;
        public StringList Skip
        {
            get { CheckDisposed(); return skip; }
            set { CheckDisposed(); skip = value; }
        }

        ///////////////////////////////////////////////////////////////////////

        private ReturnCodeDictionary returnCodeMessages;
        public ReturnCodeDictionary ReturnCodeMessages
        {
            get { CheckDisposed(); return returnCodeMessages; }
            set { CheckDisposed(); returnCodeMessages = value; }
        }

        ///////////////////////////////////////////////////////////////////////

#if DEBUGGER
        private StringDictionary breakpoints;
        public StringDictionary Breakpoints
        {
            get { CheckDisposed(); return breakpoints; }
            set { CheckDisposed(); breakpoints = value; }
        }
#endif

        ///////////////////////////////////////////////////////////////////////

        private string path;
        public string Path
        {
            get { CheckDisposed(); return path; }
            set { CheckDisposed(); path = value; }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IDisposable "Pattern" Members
        private bool disposed;
        private void CheckDisposed() /* throw */
        {
#if THROW_ON_DISPOSED
            if (disposed && Engine.IsThrowOnDisposed(null, false))
                throw new InterpreterDisposedException(typeof(TestContext));
#endif
        }

        ///////////////////////////////////////////////////////////////////////

        private /* protected virtual */ void Dispose(
            bool disposing
            )
        {
            TraceOps.DebugTrace(String.Format(
                "{0}: Dispose: called, disposing = {1}, disposed = {2}{3}",
                GlobalState.GetCurrentThreadId(), disposing, disposed,
                Environment.NewLine), typeof(TestContext).Name);

            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    threadId = 0;

                    ///////////////////////////////////////////////////////////

                    statistics = null;

                    ///////////////////////////////////////////////////////////

                    if (constraints != null)
                    {
                        constraints.Clear();
                        constraints = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (failures != null)
                    {
                        failures.Clear();
                        failures = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (counts != null)
                    {
                        counts.Clear();
                        counts = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (match != null)
                    {
                        match.Clear();
                        match = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (skip != null)
                    {
                        skip.Clear();
                        skip = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (returnCodeMessages != null)
                    {
                        returnCodeMessages.Clear();
                        returnCodeMessages = null;
                    }

                    ///////////////////////////////////////////////////////////

#if DEBUGGER
                    if (breakpoints != null)
                    {
                        breakpoints.Clear();
                        breakpoints = null;
                    }
#endif

                    ///////////////////////////////////////////////////////////

                    path = null;
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region IDisposable Members
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Destructor
        ~TestContext()
        {
            Dispose(false);
        }
        #endregion
    }
}
