#!/usr/bin/python3
import sys
import os
import re
import subprocess

import logging


    
PRINTER = os.getenv("PRINTER", "default")

    
    # 设置日志路径
    #home = os.path.expanduser('~')
home = f"/var/log/cups/"
file_name = f"usbvidpid-{PRINTER}_log"
LOG_FILE = os.path.join(home, file_name)


        # 创建日志目录（如果不存在）
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)

    # 如果日志文件不存在，则创建它并设置权限
if not os.path.exists(LOG_FILE):
    with open(LOG_FILE, 'a'):
        os.chmod(LOG_FILE, 0o640)  # 设置权限为 640 (root:lpadmin 可读写)


    # 配置日志记录器
logging.basicConfig(
        filename=LOG_FILE,
        level=logging.INFO,
        format='%(asctime)s %(levelname)s: %(message)s'
    )



def out_of_paper():
    print("no-paper: No paper in the tray")
    logging.info("打印机 没有纸张")
    sys.exit(1)



def print_error(msg):
    print(f"{msg}")
    sys.exit(1)



def print_stderr(data):
    logging.info(f"{data}")
    print(f"{data}")




def find_usblp_device_all():
    # 获取所有 /dev/usb/lpxx 设备
    devices = [f"/dev/usb/lp{x}" for x in range(0, 100)]  # 假设最多有10个打印机设备
    for device in devices:
        try:
            if not os.path.exists(device):
                continue
            print_stderr(device)
            # 执行 udevadm info 命令并获取输出
            result = subprocess.run(['udevadm', 'info', '-a', device], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
            if result.returncode != 0:
                print_stderr("跳过不存在的设备")
                continue  # 跳过不存在的设备
            
            output = result.stdout
            # 查找 VID 和 PID
            vid_match = re.search(r'ATTRS{idVendor}=="(\w+)"', output)
            pid_match = re.search(r'ATTRS{idProduct}=="(\w+)"', output)
            
            #制造商名称 产品型号
            manufacturer_match = re.search(r'ATTRS{manufacturer}=="([^"]+)"', output)
            product_match = re.search(r'ATTRS{product}=="([^"]+)"', output)
            #ieee1284_id_match = re.search(r'ATTRS{ieee1284_id}=="([^"]+)"', output)
            #{ieee1284_id_match.group(1)}
            if vid_match and pid_match:
                
                found_vid = vid_match.group(1)
                found_pid = pid_match.group(1)

                found_manufacturer="default"
                found_product="printer"
                if manufacturer_match :
                    found_manufacturer = manufacturer_match.group(1)
                if product_match:
                    found_product = product_match.group(1)
                
                name_text = f"\"usbvidpid {found_manufacturer} {found_product}\""
                if found_vid  and found_pid :
                    
                    result = f"direct usbvidpid://{found_vid}/{found_pid}/{found_product} {name_text} {name_text} {name_text} {name_text}"
                    print_stderr(result)
        except Exception as e:
            print_stderr(f"Error processing device {device}: {e}")
    


def find_usblp_device(vid, pid):
    # 获取所有 /dev/usb/lpxx 设备
    devices = [f"/dev/usb/lp{x}" for x in range(0, 100)]  # 假设最多有10个打印机设备
    for device in devices:
        try:
            if not os.path.exists(device):
                continue
            # 执行 udevadm info 命令并获取输出
            result = subprocess.run(['udevadm', 'info', '-a', device], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
            if result.returncode != 0:
                continue  # 跳过不存在的设备

            output = result.stdout
            # 查找 VID 和 PID
            vid_match = re.search(r'ATTRS{idVendor}=="(\w+)"', output)
            pid_match = re.search(r'ATTRS{idProduct}=="(\w+)"', output)

            if vid_match and pid_match:
                found_vid = vid_match.group(1).upper()
                found_pid = pid_match.group(1).upper()
                if found_vid == vid.upper() and found_pid == pid.upper():
                    return device
        except Exception as e:
            print_stderr(f"Error: processing device {device}: {e}")
    
    print_stderr(f"INFO: Device with VID: {vid} and PID: {pid} not found")
    return None


def send_data_to_printer(printer_dev, data):
    """
    将数据发送到打印机设备
    """
    try:
        with open(printer_dev, 'wb') as f:
            f.write(data)
        return True
    except Exception as e:
        print_stderr("ERROR: Failed to write to printer %s: %s" % (printer_dev, str(e)))
        return False


def main():
    args = sys.argv
    #logging.info(len(args))
    #logging.info(sys.argv)
    if len(args) == 1:
        find_usblp_device_all()
        sys.exit(0)
    if len(args) < 6 and len(args) > 1 :
        print_stderr("Usage: usbvidpid job-id user title copies options [file]")
        sys.exit(0)
    

    file_name = args[0]
    job_id = args[1]
    user = args[2]
    title = args[3]
    copies = args[4]
    options = args[5]
    logging.info("####################################################")
    print_stderr(PRINTER)
    logging.info(len(args))
    logging.info(args)
    ##获取 DEVICE_URI
    DEVICE_URI = os.getenv("DEVICE_URI", "DEVICE_URI://")
    
    # 解析 DEVICE_URI
    match = re.match(r"usbvidpid://([0-9a-fA-F]{4})/([0-9a-fA-F]{4})", DEVICE_URI)
    if not match:
        logging.error("ERROR: Invalid URI format. Expected usbvidpid://<vid>/<pid>")
        print_error("ERROR: Invalid URI format. Expected usbvidpid://<vid>/<pid>")


    target_vid = match.group(1).lower()
    target_pid = match.group(2).lower()

    print_stderr("info: Looking for USB printer with VID=%s, PID=%s" % (target_vid, target_pid))

    printer_dev = find_usblp_device(target_vid, target_pid)
    print_stderr(f"打印机：%s"%printer_dev)
    if not printer_dev:
        logging.error(f"打印机离线")
        print_error("ERROR: timed-out")
        


    print_stderr("读取打印数据")
    if len(args) > 6:
        with open(args[6], 'rb') as f:
            data = f.read()
    else:
        data = sys.stdin.buffer.read()

    print_stderr(f"数据长度 %d"%len(data))
    if not data:
        logging.error(f"没有打印数据")
        print_error("INFO: No data to print.")
    #发送打印数据
    if not send_data_to_printer(printer_dev, data):
        logging.error("打印机 繁忙")
        print_error("ERROR: Printer is currently busy")
  
    
    print("successful-ok")
    logging.info("打印成功")

    #将缓存目录同步到用户目录
    input_path = "/var/spool/cups/tmp/usbvidpid"
    out_path=""
    if user == "root":
        out_path = f"/{user}/"
    else:    
        out_path = f"/home/{user}/"
    try:
        cmd = [
            "rsync",
            "-a",
            input_path,out_path
        ]  
        result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        if result.returncode != 0:
            print_stderr(f"rsync error: {result.stderr.decode('utf-8')}")
    except Exception as e:
        print_stderr(f"Error: {str(e)}")
    #修改权限为打印用户
    dir_path = os.path.join(out_path, "usbvidpid")
    try:
        cmd = [
            "chown",
            "-R",
            f"{user}:{user}",
            dir_path
        ]  
        result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        if result.returncode != 0:
            print_stderr(f"chown error: {result.stderr.decode('utf-8')}")
    except KeyError:
        print_stderr(f"错误：用户{user}不存在")
    except PermissionError:
        print_stderr("错误：需要root权限执行此操作")
    sys.exit(0)

if __name__ == "__main__":

    main()
