/*
 * ExecuteCache.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 Eagle._Attributes;

#if CACHE_STATISTICS
using Eagle._Components.Public;
#endif

using Eagle._Containers.Private;

#if CACHE_STATISTICS
using Eagle._Containers.Public;
#endif

using Eagle._Interfaces.Public;

namespace Eagle._Components.Private
{
    [ObjectId("5fcf4ba1-d84c-46fc-84a5-14d0f98e014a")]
    internal sealed class ExecuteCache
    {
        #region Private Data
#if CACHE_STATISTICS
        internal readonly int[] cacheCounts =
            new int[(int)CacheCountType.SizeOf]; // WARNING: CACHE USE ONLY.
#endif

        private ExecuteDictionary cache;
        #endregion

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

        #region Public Constructors
        public ExecuteCache()
        {
            cache = new ExecuteDictionary();
        }
        #endregion

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

        #region Public Properties
        public int Count
        {
            get { return (cache != null) ? cache.Count : 0; }
        }
        #endregion

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

        #region Public Methods
        public void Clear()
        {
            if (cache != null)
                cache.Clear();
        }

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

        public bool TryGet(
            string name,
            bool validate,
            ref IExecute execute
            )
        {
            if ((cache != null) && (name != null))
            {
                if (cache.TryGetValue(name, out execute))
                {
                    if (!validate || (execute != null))
                        return true;
                }
            }

            return false;
        }

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

        public bool AddOrUpdate(
            string name,
            IExecute execute,
            bool invalidate
            )
        {
            if ((cache != null) && (name != null))
            {
                if (invalidate)
                {
                    cache.Clear();
                }
                else if (cache.ContainsKey(name))
                {
                    cache[name] = execute;

                    return true;
                }

                cache.Add(name, execute);

                return true;
            }

            return false;
        }

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

        public bool Rename(
            string oldName,
            string newName,
            IExecute execute,
            bool invalidate
            )
        {
            if ((cache != null) && (oldName != null) && (newName != null))
            {
                if (invalidate)
                    cache.Clear();
                else if (cache.ContainsKey(oldName))
                    cache.Remove(oldName);

                cache.Add(newName, execute);

                return true;
            }

            return false;
        }

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

        public bool Remove(
            string name,
            bool invalidate
            )
        {
            if ((cache != null) && (name != null))
            {
                if (invalidate)
                {
                    cache.Clear();

                    return true;
                }
                else if (cache.ContainsKey(name))
                {
                    return cache.Remove(name);
                }
            }

            return false;
        }

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

#if CACHE_STATISTICS
        public bool HaveCacheCounts()
        {
            if (Count > 0)
                return true;

            return FormatOps.HaveCacheCounts(cacheCounts);
        }

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

        public string CacheToString()
        {
            return StringList.MakeList(
                "count", Count, FormatOps.CacheCounts(cacheCounts));
        }
#endif
        #endregion
    }
}
