using Aitex.Core.RT.Log;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;

namespace MECF.Framework.Common.Device.Bases
{
	public class STEvents
	{
        #region Properties
		
		/// <summary>
		/// 返回工作模式模板。
		/// </summary>
		[XmlArray("STPatterns")]
		[XmlArrayItem("STPattern")]
		public List<STPatternSetting> PatternsSettings { get; set; }
		
		/// <summary>
		/// 返回预定义的事件。
		/// </summary>
		[XmlArray("STEvents")]
		public List<STEvent> Events { get; set; }


		#endregion

        #region Methods

        /// <summary>
        /// 解析配置文件中定义的事件。
        /// </summary>
        /// <param name="dicLights">
        /// 包含<see cref="SignalTowerLightBase"/>对象的字典。
        /// <remarks>
        /// <see cref="STAction"/>需要映射到相应的<see cref="SignalTowerLightBase"/>对象，因此需要传入相应的字典；
        /// 该字典在<see cref="SignalTowerBase"/>构造函数中创建。
        /// </remarks>
        /// </param>
        /// <param name="events">
        /// 返回事件字典。
        /// <remarks>
        /// 事件字典的Key为事件名称，名称为RT中注册的Bool型数据，通过DATA.Poll访问。
        /// <br/>
        /// 事件动作为<see cref="STAction"/>动作列表，表示当上述事件为True时，指定的信号塔组件执行的动作。
        /// </remarks>
        /// </param>
        public void ParseEvents(Dictionary<STLightTypes, SignalTowerLightBase> dicLights, out Dictionary<string, List<STAction>> events)
        {
            events = new Dictionary<string, List<STAction>>();

            foreach (var stEvent in Events)
            {
                // 如果相同的事件已经添加，则不再重复添加
                if (events.ContainsKey(stEvent.Name))
                    continue;

                // 字典中创建一个事件项目
                events[stEvent.Name] = new List<STAction>();

                // 解析当前事件执行的动作
                foreach (STLightTypes light in Enum.GetValues(typeof(STLightTypes)))
                {
                    var strStatus = stEvent.GetType().GetProperty(light.ToString())?.GetValue(stEvent)?.ToString().ToLower();
                    if (!string.IsNullOrEmpty(strStatus))
                    {
                        var status = SignalTowerActions.Unknown;
                        STBlinkPattern blinkPattern = null;

                        if (strStatus.Contains(SignalTowerActions.On.ToString().ToLower()))
                        {
                            status = SignalTowerActions.On;
                        }
                        else if (strStatus.Contains(SignalTowerActions.Off.ToString().ToLower()))
                        {
                            status = SignalTowerActions.Off;
                        }
                        else
                        {
                            // 使用工作模式配置中的项目
                            var pattSetting = PatternsSettings.FirstOrDefault(x =>
                                string.Compare(x.Name, strStatus, StringComparison.OrdinalIgnoreCase) == 0);

                            if (pattSetting != null)
                                blinkPattern = new STBlinkPattern(pattSetting.Pattern, pattSetting.Priority, pattSetting.Cycles);
                            else
                            {
                                LOG.Warning($"Unable to find the STPatternSetting {strStatus} from STEvents config file.");
                                blinkPattern = STBlinkPattern.GetDefaultPattern();
                            }

                   
                            status = SignalTowerActions.Customized;
                        }

                        if(dicLights.TryGetValue(light, out var part))
                            events[stEvent.Name].Add(new STAction(stEvent.Name, part, status, blinkPattern));
                        else
                            LOG.Error($"Unable to find signal tower part {light} from STEvent config file.");
                    }
                }
            }
        }

        #endregion
	}
}
