using System;
using System.Collections.Concurrent;
using System.Threading;
using UnityEngine;

namespace Alibabacloud.Rum.Unity.Worker
{
    public class ThreadedWorker : AlibabacloudWorker
    {
        private BlockingCollection<IAlibabacloudWorkerMessage> _workQueue = new();
        private Thread _workerThread;
        
        public bool IsAlive => _workerThread != null && _workerThread.IsAlive;
        
        public override void Start()
        {
            if (_workerThread != null)
            {
                return;
            }

            _workerThread = new(() => { ThreadWorker(); });
            _workerThread.Start();
        }

        public override void Stop()
        {
            if (_workerThread == null)
            {
                return;
            }
            _workQueue.CompleteAdding();
            _workerThread.Join();
            
            // Clear out thread and create a new work queue so
            // this worker can be re-used (although it shouldn't be)
            _workerThread = null;
            _workQueue = new();
        }

        public override void AddMessage(IAlibabacloudWorkerMessage message)
        {
            if (_workerThread != null)
            {
                if (!_workerThread.IsAlive)
                {
                    _workerThread = null;
                    Start();
                    // todo log
                }
            }
            _workQueue.Add(message);
        }

        internal void Kill()
        {
            _workerThread?.Abort(); // 强行终止
            _workerThread?.Join();  // 等待退出
        }

        private void ThreadWorker()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            AndroidJNI.AttachCurrentThread();
#endif
            while (!_workQueue.IsCompleted)
            {
                try
                {
                    var message = _workQueue.Take();
                    if (message != null)
                    {
                        HandleMessage(message);
                    }
                }
                catch (InvalidOperationException)
                {
                    // todo log
                    // _logger.Log(DdLogLevel.Debug, "Shutting down worker thread.");
                }
                catch (Exception e)
                {
                    // todo create error message and send.
                    // var message = ;
                    // HandleMessage(message);
                }
            }
            // todo log
        }
    }
}

