#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os
import xlrd
import xlwt
import shutil

def parse_args():
    if len(sys.argv) < 2:
        print("Usage: python3 xxx.py xxx.xls [-name sheetName]")
        sys.exit(1)
    file_path = sys.argv[1]
    sheet_name = None
    if '-name' in sys.argv:
        idx = sys.argv.index('-name')
        if idx + 1 < len(sys.argv):
            sheet_name = sys.argv[idx + 1]
        else:
            print("Error: -name 参数后需跟 sheet 名称")
            sys.exit(1)
    if not os.path.exists(file_path):
        print(f"文件 {file_path} 不存在")
        sys.exit(1)
    return file_path, sheet_name

def find_header_indices(sheet):
    header = [str(sheet.cell_value(0, col)).strip() for col in range(sheet.ncols)]
    try:
        bits_col = header.index('Bits')
        offset_col = header.index('OffsetAddress')
        regname_col = header.index('RegName')
        offsetwidth_col = header.index('OffsetWidth')
    except ValueError as e:
        print(f"表头缺失: {e}")
        sys.exit(1)
    return bits_col, offset_col, regname_col, offsetwidth_col

def process_sheet(sheet, wb, sheet_name):
    bits_col, offset_col, regname_col, offsetwidth_col = find_header_indices(sheet)
    ws = wb.add_sheet(sheet_name)
    # 复制表头
    for col in range(sheet.ncols):
        ws.write(0, col, sheet.cell_value(0, col))

    offset = 0
    reg_idx = 0
    row = 1
    while row < sheet.nrows:
        bits_start_cell = str(sheet.cell_value(row, bits_col)).strip()
        # 匹配 '31' 或 '[31:' 开头
        if bits_start_cell == '31.0' or bits_start_cell.startswith('[31:'):
            print(f"Processing row {row+1}: Bits = {bits_start_cell}")
            # replace OffsetAddress
            offset_str = f"0x{offset:02X}"
            ws.write(row, offset_col, offset_str)
            # replace RegName
            reg_str = f"reg_{reg_idx:02X}"
            ws.write(row, regname_col, reg_str)
            # 校验
            if offset // 4 != reg_idx:
                print(f"[Check] OffsetAddress {offset_str} 与 RegName {reg_str} 不匹配")
            # Bits列刷新
            offset += 4
            reg_idx += 1

            bits_sum = 0
            left = 31
            start_row = row
            # one Bits row starts and ends
            while row < sheet.nrows:
                # 复制其他列
                for col in range(sheet.ncols):
                    if col in (bits_col, offset_col, regname_col):
                        continue
                    ws.write(row, col, sheet.cell_value(row, col))

                width = (sheet.cell_value(row, offsetwidth_col))
                if width is None or width == '':
                    ws.write(row, bits_col, sheet.cell_value(row, bits_col))
                    bits_cell = str(sheet.cell_value(row, bits_col)).strip()
                    row += 1
                    if bits_cell.endswith('0]'):
                        print(f"Bits cell ends with 0, breaking at row {row}")
                        break
                    else:
                        continue

                if int(width) < 0 or int(width) > 32:
                    raise ValueError(f"OffsetWidth {width} 不在 0-32 范围内")

                width = int(width) 
                right = left - width + 1
                if left == right:
                    bits_str = f"[{left}]"
                else:
                    bits_str = f"[{left}:{right}]"

                ws.write(row, bits_col, bits_str)

                bits_sum += width

                left = right - 1
                # next row
                bits_end_cell = str(sheet.cell_value(row, bits_col)).strip()
                if bits_end_cell == '0' or bits_start_cell.endswith('0]') or right == 0:
                    row += 1
                    print(f"The 0 is bits_end_cell")
                    break
                row += 1

            if bits_sum != 32:
                print(f"[Warning] {sheet_name} 第{start_row+1}行起 OffsetWidth 累加为{bits_sum}，应为32")
        else:
            # 其他行保持原样
            ws.write(row, offset_col, sheet.cell_value(row, offset_col))
            ws.write(row, regname_col, sheet.cell_value(row, regname_col))
            ws.write(row, bits_col, sheet.cell_value(row, bits_col))
            row += 1

def main():
    file_path, sheet_name = parse_args()
    # 先备份原文件
    shutil.copyfile(file_path, file_path + ".bak")
    book = xlrd.open_workbook(file_path)
    wb = xlwt.Workbook()
    sheets = [sheet_name] if sheet_name else book.sheet_names()
    print(sheets)
    for name in sheets:
        sheet = book.sheet_by_name(name)
        process_sheet(sheet, wb, name)
    # 覆盖原文件
    wb.save(file_path)
    print(f"已刷新并覆盖原文件: {file_path}，原文件已备份为: {file_path}.bak")

if __name__ == "__main__":
    main()