using System.Collections.Generic;

namespace Aitex.Core.RT.IOCore;

/// <summary>
/// 互锁动作接口。
/// </summary>
public interface IInterlockAction
{
    #region Properties

    /// <summary>
    /// 返回当前动作的名称。
    /// <remarks>
    /// 通常返回当前动作对应的DO名称。
    /// </remarks>
    /// </summary>
    string ActionName { get; }

    /// <summary>
    /// 返回当前动作的限制条件。
    /// </summary>
    IEnumerable<IInterlockLimit> Limits { get; }

    /// <summary>
    /// 返回当前动作限制条件中的“逻辑与”组。
    /// <remarks>
    /// “逻辑与”组由多个Limit对象构成，若其中任意一个Limit命中，则当前组命中。
    /// </remarks>
    /// </summary>
    IEnumerable<IEnumerable<IInterlockLimit>> LogicOrGroups { get; }

    #endregion

    #region Methods

    /// <summary>
    /// 判断当前动作是否和给定的条件一致，若一致，则表明当前动作与特定条件的动作为同一动作。
    /// </summary>
    /// <remarks>
    /// 对比时忽略OO名称大小写。
    /// </remarks>>
    /// <param name="doName">DO名称</param>
    /// <param name="value">DO目标输出</param>
    /// <returns></returns>
    bool IsSame(string doName, bool value);

    /// <summary>
    /// 增加一个限制条件。
    /// </summary>
    /// <param name="limit"></param>
    void AddLimit(IInterlockLimit limit);

    /// <summary>
    /// 增加一个“逻辑与”组。
    /// </summary>
    /// <param name="group"></param>
    void AddLogicOrGroup(List<IInterlockLimit> group);

    /// <summary>
    /// 判断当前动作是否允许执行。
    /// <remarks>
    /// 当前动作的所有Limit均命中时，允许执行。
    /// </remarks>
    /// </summary>
    /// <param name="reason"></param>
    /// <returns></returns>
    bool CanDo(out string reason);

    /// <summary>
    /// 扫描线程周期性执行的任务。
    /// </summary>
    void Monitor();

    #endregion


}