import threading
from collections import deque
import numpy as np
import time
import copy
import queue

class ChannelData:
    def __init__(self, str_url, int_type, bool_run, deque_length,icount_max):
        self.cap = None
        self.str_url = str_url  #视频源地址
        self.int_type = int_type  #视频源类型,0-usb,1-rtsp,2-hksdk
        self.bool_run = bool_run  #线程运行标识
        self.deque_frame = deque(maxlen=deque_length)
        self.last_frame = None  # 保存图片数据
        self.frame_queue = queue.Queue(maxsize=1)
        self.counter = 0  #帧序列号--保存报警录像使用
        self.icount_max = icount_max #帧序列号上限
        self.lock = threading.RLock()  # 用于保证线程安全

    #添加一帧图片
    def add_deque(self, value):
        self.deque_frame.append(value)  #deque 满了以后会把前面的数据移除

    #拷贝一份数据
    def copy_deque(self):
        return copy.deepcopy(self.deque_frame)

    #获取最后一帧图片
    def get_last_frame(self):
        with self.lock:
            frame = self.last_frame
        return frame
        # if not self.frame_queue.empty():
        #     return self.frame_queue.get()
        # else:
        #     return None


    def update_last_frame(self,buffer):
        if buffer:
            with self.lock:
                self.last_frame = None
                self.last_frame = buffer
            # if not self.frame_queue.full():
            #     self.frame_queue.put(buffer)
            # else:
            #     self.frame_queue.get()  # 丢弃最旧的帧
            #     self.frame_queue.put(buffer)


    #帧序列号自增 一个线程中处理,不用加锁
    def increment_counter(self):
        self.counter += 1
        if self.counter > self.icount_max:
            self.counter = 0

    def get_counter(self):
        return self.counter

    #清空数据,主要是删除deque 和 last_frame
    def clear(self):
        with self.lock:
            self.bool_run = False
            time.sleep(1)   #休眠一秒,等待通道对应的子线程,停止工作。
            self.deque_frame.clear()
            self.last_frame = None

    def stop_run(self):
        self.bool_run = False


class ChannelManager:
    def __init__(self):
        self.channels = {}
        self.lock = threading.RLock()  # 用于保证字典操作的线程安全

    #增加节点
    def add_channel(self, channel_id, str_url, int_type, bool_run, deque_length=10,icount_max=100000):
        with self.lock:
            if channel_id in self.channels:     #若已经有数据,先删除后再增加
                self.channels[channel_id].clear()  # 手动清理资源
                del self.channels[channel_id]
            ch_data = ChannelData(str_url, int_type, bool_run, deque_length, icount_max)
            self.channels[channel_id] = ch_data
            return ch_data

    #删除节点
    def delete_channel(self, channel_id):
        with self.lock:
            if channel_id in self.channels:
                self.channels[channel_id].clear()  # 手动清理资源
                del self.channels[channel_id]

    #获取节点
    def get_channel(self, channel_id):
        with self.lock:
            return self.channels.get(channel_id)

    #停止工作线程---要把视频采集线程停止掉
    def stop_channel(self,channel_id):
        with self.lock:
            if channel_id == 0:
                for clannel_id,clannel_data in self.channels.items():
                    clannel_data.cap.running = False
                    clannel_data.clear()    #clear 里面已经停止了通道的工作线程
                del self.channels
            else:
                if channel_id in self.channels:
                    self.channels[channel_id].cap.running = False
                    self.channels[channel_id].clear()  # 手动清理资源
                    del self.channels[channel_id]

if __name__ == "__main__":
    # 示例使用
    manager = ChannelManager()
    manager.add_channel('channel_1', 'test', 123, True, deque_length=5)

    # 更新和读取操作
    manager.update_channel_deque('channel_1', 'data1')
    manager.update_channel_buffer('channel_1', np.array([[1, 2], [3, 4]]))
    manager.increment_channel_counter('channel_1')

    channel_data = manager.get_channel_data('channel_1')
    print(channel_data)