from libedaio import EdaIo,registerInput,registerTrigger,registerTune
import time
import os
from PIL import Image
from picamera2 import Picamera2

MAXT_TEST = 40000
MAXT_TEST_LIQUID = 1000

class Tester:
    def __init__(self):
        self.t_index_trig = 0
        self.is_do1 = True
        self.eda = EdaIo.singleton()
        self.eda.setup()
        time.sleep(0.1)
        registerInput(self.callback_input)
        # registerTrigger(self.callback_trigger)
        registerTune(self.callback_tune)

    def test(self):
        for i in range(1,5):
            self.eda.disableLightSection(i)
        
        for j in range(MAXT_TEST):
            print("[Test] index:",j)
            for i in range(1,5):
                # RGB 测试
                self.eda.setRgbLight((j*4+i)%4)
                # 状态灯、故障灯、激光
                if i%2 == 0:
                    self.eda.openLaser()
                    self.eda.setScanStat(True)
                    self.eda.openAlarm()
                else:
                    self.eda.closeLaser()
                    self.eda.setScanStat(False)
                    self.eda.closeAlarm()

                # 光源测试
                self.eda.enableLightSection(i)
                self.eda.open_light()
                time.sleep(0.1)
                self.eda.close_light()
                self.eda.disableLightSection(i)
                time.sleep(0.1)

    def test_DODI(self, is_do1: bool = True):
        self.is_do1 = is_do1
        self.t_index_trig = 0
        if self.is_do1:
            os.system("raspi-gpio set 27 op pd")
        else:
            os.system("raspi-gpio set 22 op pd")
        for i in range(MAXT_TEST):
            if self.is_do1:
                self.eda.setDo1High(False)
                time.sleep(0.1)
                self.eda.setDo1High(True)
                time.sleep(0.1)
            else:
                self.eda.setDo2High(False)
                time.sleep(0.1)
                self.eda.setDo2High(True)
                time.sleep(0.1)

    def callback_input(self, v):
        if v == 1:
            self.t_index_trig = self.t_index_trig + 1
            if self.is_do1:
                print(f"[Debug] Do + DO1 Trig: {self.t_index_trig}") 
            else:
                print(f"[Debug] Do + DO2 Trig: {self.t_index_trig}") 
    
    def test_dodi_result(self):
        if MAXT_TEST == self.t_index_trig:
            return True
        return False
    
    def test_liquid(self):
        self.picam2 = Picamera2()
        self.picam2.start()
        focus_params = [11000, 22000, 33000, 44000]
        failed_nm = 0
        os.system("mkdir -p /home/pi/test_loop/images")
        os.system("rm -f /home/pi/test_loop/images/*")
        for j in range(MAXT_TEST_LIQUID):
            self.eda.open_light()
            for i, param in enumerate(focus_params, 1):
                self.eda.setLiquid(param)
                time.sleep(0.5)
                self.eda.callLightFlash()
                self.picam2.capture_file(f"/tmp/lens_{i}.jpg")
            composite_success = self._generate_composite([
                f"/tmp/lens_{i}.jpg" for i in range(1, 5)
            ], f"/home/pi/test_loop/images/lens_{j}.jpg")
            if not composite_success:
                failed_nm = failed_nm + 1
                print(f"[Err] index: {j}, {failed_nm}")
            else:
                print(f"Success: {j}")
            self.eda.close_light()
            time.sleep(1)

    def _generate_composite(self, image_paths, composite_path):
        try:
            
            images = [Image.open(path) for path in image_paths]
            canvas = Image.new("RGB", (1024, 768))
            
            positions = [
                (0, 0),                 # 左上
                (512, 0),               # 右上 
                (0, 384),               # 左下
                (512, 384)              # 右下
            ]
            
            for img, pos in zip(images, positions):
                canvas.paste(img.resize((512, 384)), pos)
            
            # composite_path = "/tmp/lens_composite.jpg"
            canvas.save(composite_path)
            return True
            
        except Exception as e:
            self.bridge.write(f"COMPOSITE_ERROR:{str(e)}\n")
            return False

    def callback_tune(self, v):
        self.eda.close_light()
        self.eda.closeLaser()
        self.eda.setScanStat(False)
        self.eda.closeAlarm()
        for i in range(1,5):
            self.eda.enableLightSection(i)
        os.system("sudo shutdown -h now")

if __name__ == "__main__":
    print("start test...")
    tester = Tester()
    tester.test()
    time.sleep(2)
