# --- shared.py ---
import asyncio
import json
import os

DEBUG_MODE = False 

def debug_print(msg: str):
    if DEBUG_MODE:
        print(msg)

# 預設的 CMTS 連線樣板
CMTS_DEVICE = {
    'device_type': 'cisco_ios',
    'host': '10.14.110.4',
    'username': 'admin',
    'password': 'nsgadmin',
    'port': 22,
    'fast_cli': False,
    'global_delay_factor': 2
}

def parse_cli_to_tree(cli_text: str) -> dict:
    """
    將 CMTS 的 CLI 配置文字，根據縮排轉換為巢狀 JSON (Dictionary)
    """
    # 過濾掉空行與註解 (!)
    lines = [line for line in cli_text.splitlines() if line.strip() and line.strip() != '!']
    
    def parse_block(start_idx: int, base_indent: int):
        block = {}
        i = start_idx
        while i < len(lines):
            line = lines[i]
            indent = len(line) - len(line.lstrip())
            
            if indent < base_indent:
                break
                
            content = line.strip()
            
            has_children = False
            if i + 1 < len(lines):
                next_indent = len(lines[i+1]) - len(lines[i+1].lstrip())
                if next_indent > base_indent:
                    has_children = True
            
            if has_children:
                child_block, next_i = parse_block(i + 1, next_indent)
                block[content] = child_block
                i = next_i
            else:
                parts = content.split(maxsplit=1)
                if len(parts) == 2:
                    block[parts[0]] = parts[1]
                else:
                    block[parts[0]] = "" 
                i += 1
                
        return block, i

    tree, _ = parse_block(0, 0)
    return tree

def deep_split_tree(data):
    """將平坦的 CLI 字典，依照空白字元拆分成深層巢狀結構 (具備型態衝突保護)"""
    if not isinstance(data, dict):
        return data
        
    nested_tree = {}
    for key, value in data.items():
        # 1. 遞迴處理子節點
        processed_value = deep_split_tree(value)
        
        # 2. 將當前的 key 依照空白拆分
        parts = str(key).strip().split()
        if not parts:
            continue
            
        # 3. 依序建立深層結構
        current = nested_tree
        for i, part in enumerate(parts):
            if i == len(parts) - 1:
                # 抵達最後一個單字，準備塞入值
                if part not in current:
                    current[part] = processed_value
                else:
                    # 💡 衝突保護：如果節點已存在，根據型態進行安全合併
                    if isinstance(current[part], dict) and isinstance(processed_value, dict):
                        current[part].update(processed_value)
                    elif isinstance(current[part], dict) and not isinstance(processed_value, dict):
                        # 原本是資料夾，新來的是字串 -> 保留資料夾
                        pass
                    elif not isinstance(current[part], dict) and isinstance(processed_value, dict):
                        # 原本是字串，新來的是資料夾 -> 升級成資料夾
                        current[part] = processed_value
                    else:
                        # 兩者都是字串，直接覆蓋
                        current[part] = processed_value
            else:
                # 建立中間的階層
                if part not in current:
                    current[part] = {}
                elif not isinstance(current[part], dict):
                    # 💡 衝突保護：如果中間節點原本被當作字串，強制升級為字典(資料夾)以便容納子節點
                    current[part] = {}
                    
                current = current[part]
                
    return nested_tree

# ==========================================
# 💡 系統設定管理 (System Settings Manager)
# ==========================================
SETTINGS_FILE = "system_settings.json"

def load_settings():
    """讀取系統設定，若檔案不存在則回傳預設的黑名單"""
    if os.path.exists(SETTINGS_FILE):
        try:
            with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
                return json.load(f)
        except Exception:
            pass
    # 預設隱藏這些比較雜亂且不常修改的系統層級設定
    return {"hidden_keys": ["logging", "privilege", "aaa", "certificate", "line"]}

def save_settings(settings_data):
    """將系統設定寫入 JSON 檔案"""
    with open(SETTINGS_FILE, "w", encoding="utf-8") as f:
        json.dump(settings_data, f, indent=4, ensure_ascii=False)

# 全域非同步鎖：確保同一時間只有一人能執行設定寫入
cmts_config_lock = asyncio.Lock()
