#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""sua_duong_dan.py — vá đường dẫn Windows -> Linux cho 3 app (HLQT/CSDL A · CALIB/CSDL B · Agent-Lab).

Chạy:  python3 cai_dat/sua_duong_dan.py           (sửa thật)
       python3 cai_dat/sua_duong_dan.py --kiem    (chỉ kiểm, không sửa)

LƯU Ý KỸ THUẬT: trong file nguồn, đường dẫn Windows chỉ có MỘT dấu gạch chéo ngược,
nên pattern regex (chuỗi raw) phải viết HAI gạch: r"C:\\Claw" — viết 4 gạch là SAI (không khớp).
"""
import json
import os
import re
import sys

CAI = os.path.dirname(os.path.abspath(__file__))
BO = os.path.dirname(CAI)
CFG = json.load(open(os.path.join(CAI, 'cau_hinh.json'), encoding='utf-8'))
ROOT = CFG['root'].rstrip('/')
AGY = CFG['agy_bin']
URL = (CFG.get('url_public') or '').rstrip('/')
CHI_KIEM = '--kiem' in sys.argv

# ── 1. vá theo từng app (hằng số GOC/APP/DB riêng của mỗi app)
THEO_APP = {
    'hlqt': [
        (r"GOC = r'C:\\Claw 2\\Nghien cuu\\Du-an-A-Quy-trinh-son'", "GOC = r'%s/apps/hlqt'" % ROOT),
        (r"APP = os\.path\.join\(GOC, 'HLQT-app'\)", "APP = GOC"),
        (r"DB = os\.path\.join\(GOC, 'CSDLA\.db'\)", "DB = r'%s/data/CSDLA.db'" % ROOT),
        (r"OUT = os\.path\.join\(GOC, 'HLQT-app', 'kien_thuc', 'CSDLA_GOI_CHO_AGY\.md'\)",
         "OUT = os.path.join(GOC, 'kien_thuc', 'CSDLA_GOI_CHO_AGY.md')"),
    ],
    'calib': [
        (r"GOC = r'C:\\Claw 2\\Nghien cuu\\Du-an-B-He-mau-Stain-Glaze\\calib-app'", "GOC = r'%s/apps/calib'" % ROOT),
        (r"DB = r'C:\\Claw 2\\Nghien cuu\\Du-an-B-He-mau-Stain-Glaze\\CSDLB\.db'", "DB = r'%s/data/CSDLB.db'" % ROOT),
    ],
    'lab': [
        (r"GOC = r'C:\\Claw 2\\Nghien cuu\\Agent-Lab'", "GOC = r'%s/apps/lab'" % ROOT),
        (r"DB = os\.path\.join\(GOC, 'lab\.db'\)", "DB = r'%s/data/lab.db'" % ROOT),
        (r"D_DB = r'C:\\Claw 2\\Nghien cuu\\Du-an-D-Ho-so-vat-lieu\\CSDLD\.db'", "D_DB = r'%s/data/CSDLD.db'" % ROOT),
    ],
}

# ── 2. vá dùng chung mọi file .py
CHUNG = [
    (r"C:\\Claw 2\\Nghien cuu\\Du-an-A-Quy-trinh-son\\CSDLA\.db", ROOT + '/data/CSDLA.db'),
    (r"C:\\Claw 2\\Nghien cuu\\Du-an-B-He-mau-Stain-Glaze\\CSDLB\.db", ROOT + '/data/CSDLB.db'),
    (r"C:\\Claw 2\\Nghien cuu\\Du-an-D-Ho-so-vat-lieu\\CSDLD\.db", ROOT + '/data/CSDLD.db'),
    (r"C:\\Claw-Zalo\\CSDLC\\CSDLC\.db", ROOT + '/data/CSDLC.db'),
    (r"C:\\Users\\admin\\AppData\\Local\\agy\\bin\\agy\.exe", AGY),
    (r"C:\\Claw 2\\QC\\_md2docx\.py", ROOT + '/cai_dat/md2docx.py'),
    (r"C:/Claw 2/QC/_md2docx\.py", ROOT + '/cai_dat/md2docx.py'),
    # gốc còn sót của từng app (file _tools)
    (r"C:\\Claw 2\\Nghien cuu\\Du-an-A-Quy-trinh-son", ROOT + '/apps/hlqt'),
    (r"C:\\Claw 2\\Nghien cuu\\Du-an-B-He-mau-Stain-Glaze\\calib-app", ROOT + '/apps/calib'),
    (r"C:\\Claw 2\\Nghien cuu\\Agent-Lab", ROOT + '/apps/lab'),
    # script gửi mail (biểu thức 2 dòng của os.path.expandvars)
    (r"os\.path\.join\(os\.path\.expandvars\(r'%LOCALAPPDATA%'\),\s*'hermes',\s*'skills',\s*'email',\s*'gui-email-kem-file',\s*'scripts',\s*'gui_mail_kem_file\.py'\)",
     "r'%s/cai_dat/gui_mail_kem_file.py'" % ROOT),
    # thư mục token Google của máy cũ (thay CẢ biểu thức — replacement phải KHÔNG chứa dấu \)
    (r"os\.path\.expandvars\(r'%LOCALAPPDATA%'\)", "os.path.expanduser('~/.config/btchem')"),
    (r"os\.path\.expandvars\(r'%LOCALAPPDATA%\\hermes\\google_token\.json'\)",
     "os.path.expanduser('~/.config/btchem/google_token.json')"),
    (r"'C:/tmp'", "'/tmp'"),
]
if URL:
    CHUNG.append((r"URL_PUBLIC = 'https://[^']*'", "URL_PUBLIC = '%s/'" % URL))
else:
    CHUNG.append((r"URL_PUBLIC = 'https://[^']*'", "URL_PUBLIC = ''   # không dùng truy cập từ xa (đặt url_public trong cau_hinh.json nếu cần)"))


def sua_file(p, app):
    goc = open(p, encoding='utf-8', errors='replace').read()
    moi, dem = goc, 0
    for rgx, thay in THEO_APP.get(app, []) + CHUNG:
        try:
            moi, n = re.subn(rgx, thay, moi)
        except Exception as e:
            print('   ✗ LỖI VÁ ở %s\n     pattern: %r\n     thay   : %r\n     lỗi    : %s'
                  % (os.path.basename(p), rgx, thay, e))
            continue
        dem += n
    if dem and not CHI_KIEM:
        open(p, 'w', encoding='utf-8').write(moi)
    return dem


tong = {}
for app in ('hlqt', 'calib', 'lab'):
    for thu_muc, _, ten_file in os.walk(os.path.join(BO, 'apps', app)):
        for f in ten_file:
            if f.endswith('.py'):
                n = sua_file(os.path.join(thu_muc, f), app)
                if n:
                    tong[os.path.relpath(os.path.join(thu_muc, f), BO)] = n

print('  === số chỗ đã %s ===' % ('KIỂM' if CHI_KIEM else 'VÁ'))
for k in sorted(tong):
    print('   %-52s %d' % (k, tong[k]))
print('   TỔNG:', sum(tong.values()))

# ── 3. kiểm sót
con, loi = [], []
for app in ('hlqt', 'calib', 'lab'):
    for thu_muc, _, ten_file in os.walk(os.path.join(BO, 'apps', app)):
        for f in ten_file:
            if not f.endswith('.py'):
                continue
            p = os.path.join(thu_muc, f)
            src = open(p, encoding='utf-8', errors='replace').read()
            for i, dong in enumerate(src.split('\n'), start=1):
                if re.search(r"[A-Za-z]:\\\\|C:/|%LOCALAPPDATA%", dong):
                    con.append('%s:%d  %s' % (os.path.relpath(p, BO), i, dong.strip()[:100]))
            try:
                compile(src, p, 'exec')          # kiểm cú pháp, KHÔNG ghi file
            except Exception as e:
                loi.append('%s — %s' % (os.path.relpath(p, BO), str(e)[:110]))

print()
print('  còn đường dẫn Windows:', len(con))
for x in con[:15]:
    print('    ⚠', x)
print('  lỗi cú pháp Python:', len(loi))
for x in loi[:10]:
    print('    ✗', x)
print()
print('  root = %s | agy = %s | url = %s' % (ROOT, AGY, URL or '(trống)'))
print('  ✓ SẠCH — sẵn sàng chạy app.' if not con and not loi else '  ⚠ CÒN VẤN ĐỀ — xử lý trước khi chạy.')
