// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

namespace System.Data.Entity.Core.Query.InternalTrees
{
    // <summary>
    // A RuleProcessingContext encapsulates information needed by various rules to process
    // the query tree.
    // </summary>
    internal abstract class RuleProcessingContext
    {
        #region public surface

        internal Command Command
        {
            get { return m_command; }
        }

        // <summary>
        // Callback function to be applied to a node before any rules are applied
        // </summary>
        // <param name="node"> the node </param>
        internal virtual void PreProcess(Node node)
        {
        }

        // <summary>
        // Callback function to be applied to the subtree rooted at the given
        // node before any rules are applied
        // </summary>
        // <param name="node"> the node that is the root of the subtree </param>
        internal virtual void PreProcessSubTree(Node node)
        {
        }

        // <summary>
        // Callback function to be applied on a node after a rule has been applied
        // that has modified the node
        // </summary>
        // <param name="node"> current node </param>
        // <param name="rule"> the rule that modified the node </param>
        internal virtual void PostProcess(Node node, Rule rule)
        {
        }

        // <summary>
        // Callback function to be applied to the subtree rooted at the given
        // node after any rules are applied
        // </summary>
        // <param name="node"> the node that is the root of the subtree </param>
        internal virtual void PostProcessSubTree(Node node)
        {
        }

        // <summary>
        // Get the hashcode for this node - to ensure that we don't loop forever
        // </summary>
        // <param name="node"> current node </param>
        // <returns> int hashcode </returns>
        internal virtual int GetHashCode(Node node)
        {
            return node.GetHashCode();
        }

        #endregion

        #region constructors

        internal RuleProcessingContext(Command command)
        {
            m_command = command;
        }

        #endregion

        #region private state

        private readonly Command m_command;

        #endregion
    }
}
