using System;
using System.Collections.Generic;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;

namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.Filters
{
    public abstract class FilterBase : IFilter, IDisposable
    {
        #region Variables

        private const int MAX_BUFFER_SIZE = 100000;

        private readonly R_TRIG _rTrigFilterError = new();

        protected readonly string ScBase;
        protected readonly Queue<TempPoint> DataBuffer = [];

        #endregion

        public FilterBase(string module, string filterName, string scBasePath)
        {
            Module = module;
            FilterName = filterName;
            ScBase = scBasePath;
        }

        public string Module { get; }

        public string FilterName { get; }

        public virtual bool Initialize(out string reason)
        {
            reason = "";
            return true;
        }

        public virtual double Update(double data)
        {
            if (DataBuffer.Count >= MAX_BUFFER_SIZE)
                DataBuffer.Dequeue();

            DataBuffer.Enqueue(new TempPoint(data));

            try
            {
                var ret = HandleFilter(data);
                _rTrigFilterError.CLK = false;
                return ret;
            }
            catch (Exception ex)
            {
                _rTrigFilterError.CLK = true;
                if(_rTrigFilterError.Q)
                    LOG.Error($"{FilterName} Filter error, {ex.Message}", ex);
                return data;
            }
        }

        public virtual void Reset()
        {
            DataBuffer.Clear();
            _rTrigFilterError.RST = true;
        }

        protected virtual double HandleFilter(double lastTemp)
        {
            throw new NotImplementedException();
        }

        public void Dispose()
        {
            DataBuffer?.Clear();
        }
    }
}
