# -*- coding: utf-8 -*-
"""SINH_THAMSO.PY — sinh tai lieu THAM SO tu ma nguon EA. Chay lai duoc.

NGUYEN TAC (chu du an dat ra): "cay module la phan cung, phan dien giai la
phan di kem". Nen tep nay sinh PHAN CUNG — ten input, gia tri mac dinh, chu
thich trong ma — con PHAN DIEN GIAI (khi nao nen doi, doi thi anh huong gi)
thi viet tay trong tep dien_giai.json roi dan de len.

Hai cho LAP LAI duoc gop lai, dung yeu cau chu du an:
  - VII.1 .. VII.5  nam khung gio, CUNG MOT KHUON -> ta mot lan
  - XII.1 .. XII.28 hai muoi tam bo loc, cung khuon -> ta khuon + bang rieng

Chay:  python sinh_thamso.py <thu_muc_ea> <tep_ra.md>
"""
import io, json, os, re, sys
from datetime import date

GOC = sys.argv[1] if len(sys.argv) > 1 else r'G:/server tin hieu/systemai/dca/ea'
RA = sys.argv[2] if len(sys.argv) > 2 else 'THAM_SO.md'
DIEN_GIAI = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'dien_giai.json')

TEP_INPUT = 'include/config/DCA_Inputs.mqh'   # ban INPUT_DEFAULT dang phat hanh

# NHOM NOI BO — khong dua vao tai lieu khach doc. Chu du an dan 23/09/2026:
# "hai nhom do giu noi bo, ko dua vao tai lieu khach".
#   XVII  = thu nghiem / chan doan (chua ca DCA_EarlyCut, ban phat hanh khong co)
#   XVIII = AI Sender (telemetry gui ve Tram Gac AI)
# Sinh ra HAI tep: ban khach da loc, va ban day du cho noi bo.
NHOM_NOI_BO = ('XVII.', 'XVIII.')


def la_noi_bo(ten):
    return any(ten.startswith(x) for x in NHOM_NOI_BO)

MAU_NHOM = re.compile(r'\s*input group "=+\s*(.+?)\s*=+"')
MAU_INPUT = re.compile(
    r'\s*(?:input|sinput)\s+\S+\s+(\w+)\s*=\s*([^;]+);\s*(?://\s*(.*))?')


def doc(p):
    for bm in ('utf-8', 'utf-8-sig', 'cp1258', 'latin-1'):
        try:
            return io.open(p, encoding=bm).read()
        except (UnicodeDecodeError, LookupError):
            continue
    return ''


def quet(s):
    """Tra [(ten_nhom, [(ten, mac_dinh, chu_thich), ...]), ...]."""
    ra, hien, ds = [], None, []
    for d in s.splitlines():
        m = MAU_NHOM.match(d)
        if m:
            if hien is not None:
                ra.append((hien, ds))
            hien, ds = m.group(1), []
            continue
        mm = MAU_INPUT.match(d)
        if mm and hien is not None:
            ten, mac_dinh, ct = mm.group(1), mm.group(2).strip(), (mm.group(3) or '').strip()
            ct = re.sub(r'^\d+[.)]\s*', '', ct)       # bo so thu tu dau chu thich
            ds.append((ten, mac_dinh, ct))
    if hien is not None:
        ra.append((hien, ds))
    return ra


def la_khung_gio(ten):
    return re.match(r'VII\.[1-5]\s', ten) is not None


def la_bo_loc(ten):
    return re.match(r'XII\.([1-9]|1\d|2[0-8])\s', ten) is not None


def mot_o(s):
    """Nhet van ban nhieu dong vao MOT o bang markdown.

    Xuong dong that se lam VO bang — cac dong sau roi ra ngoai bang. Doi
    thanh <br>, va thoat dau | vi no la ky tu ngan cot.
    """
    return (s.replace('|', r'\|')
             .replace('\n\n', '<br><br>')
             .replace('\n', '<br>'))


def bang(ds, dg):
    d = ['| Tham số | Mặc định | Nghĩa là gì |', '|---|---|---|']
    for ten, mac_dinh, ct in ds:
        mo = dg.get(ten) or ct or '—'
        d.append('| `%s` | `%s` | %s |' % (ten, mac_dinh[:28], mot_o(mo)))
    return '\n'.join(d)


def main():
    s = doc(os.path.join(GOC, TEP_INPUT))
    if not s:
        print('KHONG DOC DUOC', TEP_INPUT); return 1
    nhom_tat_ca = quet(s)
    dg = {}
    if os.path.isfile(DIEN_GIAI):
        dg = json.load(io.open(DIEN_GIAI, encoding='utf-8'))

    cho_khach = os.environ.get('BAN_NOI_BO', '') != '1'
    nhom = [n for n in nhom_tat_ca if not (cho_khach and la_noi_bo(n[0]))]
    da_loc = len(nhom_tat_ca) - len(nhom)

    tong_input = sum(len(x) for _, x in nhom)
    kg = [n for n in nhom if la_khung_gio(n[0])]
    bl = [n for n in nhom if la_bo_loc(n[0])]
    con = [n for n in nhom if not la_khung_gio(n[0]) and not la_bo_loc(n[0])]

    r = []
    r.append('# SMART DCA EA v11.9 — Tham số đầy đủ')
    r.append('')
    r.append('> **Tệp này SINH TỰ ĐỘNG từ mã nguồn** bằng `sinh_thamso.py`, ngày %s.'
             % date.today().isoformat())
    r.append('> Đừng sửa tay — lần sinh sau sẽ đè lên. Muốn đổi phần *nghĩa là gì*')
    r.append('> thì sửa `dien_giai.json`; muốn đổi phần còn lại thì sửa chú thích')
    r.append('> ngay trong `%s`.' % TEP_INPUT)
    r.append('')
    r.append('Bản đang phát hành biên dịch với `INPUT_DEFAULT`. Ba bản còn lại')
    r.append('(`INPUT_DAILY`, `INPUT_THUE`, `INPUT_DAOTHANTAI`) là bản dựng riêng,')
    r.append('khách không gặp.')
    r.append('')
    r.append('**%d nhóm · %d tham số.** Trong đó %d nhóm là lặp lại theo khuôn:'
             % (len(nhom), tong_input, len(kg) + len(bl)))
    r.append('%d khung giờ và %d bộ lọc — mô tả một lần ở cuối, không lặp.'
             % (len(kg), len(bl)))
    if da_loc:
        r.append('')
        r.append('*(%d nhóm nội bộ đã lọc khỏi bản này: thử nghiệm/chẩn đoán và '
                 'telemetry. Xem bản đầy đủ nếu cần.)*' % da_loc)
    r.append('')
    r.append('---')
    r.append('')

    # ---- cac nhom rieng biet ----
    for ten, ds in con:
        r.append('## %s' % ten)
        r.append('')
        if ds:
            r.append(bang(ds, dg))
        else:
            r.append('*(nhóm không có tham số trực tiếp)*')
        r.append('')

    # ---- khuon khung gio ----
    if kg:
        r.append('---')
        r.append('')
        r.append('## Năm khung giờ — một khuôn dùng chung')
        r.append('')
        r.append('Năm nhóm `VII.1` … `VII.5` **giống hệt nhau về cấu trúc**, chỉ khác')
        r.append('số thứ tự ở cuối tên tham số (`InpTimeRange1` … `InpTimeRange5`).')
        r.append('Mỗi khung giờ là một bộ cài đặt DCA riêng, áp dụng trong đúng')
        r.append('khoảng giờ khai ở `InpTimeRange<n>`. Ngoài mọi khung giờ thì EA')
        r.append('làm theo nhóm `VII.6`.')
        r.append('')
        r.append('Dưới đây là khung giờ 1 làm mẫu — bốn khung còn lại đọc y hệt:')
        r.append('')
        r.append(bang(kg[0][1], dg))
        r.append('')

    # ---- khuon bo loc ----
    if bl:
        r.append('---')
        r.append('')
        r.append('## %d bộ lọc — một khuôn dùng chung' % len(bl))
        r.append('')
        r.append('Mỗi bộ lọc đều có cùng bộ xương: **bật/tắt · khung thời gian ·')
        r.append('chu kỳ · ngưỡng**. Bật lên thì bộ lọc chặn không cho mở lệnh khi')
        r.append('điều kiện của nó đúng. Hành động khi filter đổi trạng thái khai ở')
        r.append('nhóm `XII.29`, dùng chung cho mọi bộ lọc.')
        r.append('')
        r.append('| Bộ lọc | Số tham số | Tham số riêng đáng chú ý |')
        r.append('|---|---|---|')
        for ten, ds in bl:
            ten_ngan = re.sub(r'^XII\.\d+\s+LỌC\s*', '', ten)
            rieng = [t for t, _, _ in ds
                     if not any(k in t for k in ('Enable', 'Timeframe', 'Period'))]
            r.append('| %s | %d | %s |'
                     % (ten_ngan, len(ds), ', '.join('`%s`' % x for x in rieng[:3]) or '—'))
        r.append('')
        # TRƯỚC 23/09/2026 chỗ này chỉ in MỘT bảng ví dụ (bộ lọc đầu tiên,
        # tức RSI) rồi thôi. Hợp lý lúc đó, vì chỉ RSI có diễn giải viết
        # tay — 27 bộ còn lại in ra cũng chỉ là bảng tên tham số trống
        # rỗng, không hơn gì bảng tóm tắt ở trên.
        #
        # Nay cả 138 tham số của 27 bộ kia đều đã có diễn giải riêng, và
        # chúng KHÁC NHAU thật: mỗi chỉ báo đo một thứ, hướng chặn cũng
        # khác (dao động chặn theo chiều · xu hướng chặn cả hai · kênh giá
        # chặn khi phá biên · OBV chặn ngược dòng tiền). Gộp tiếp là giấu
        # mất phần tri thức đáng giá nhất, nên in đủ.
        #
        # Bảng tóm tắt ở trên GIỮ NGUYÊN — nó vẫn là chỗ nhìn một cái thấy
        # hết 28 bộ lọc, thứ mà 28 bảng rời không thay thế được.
        r.append('---')
        r.append('')
        r.append('### Chi tiết từng bộ lọc')
        r.append('')
        for ten, ds in bl:
            r.append('#### %s' % re.sub(r'^XII\.\d+\s+', '', ten))
            r.append('')
            r.append(bang(ds, dg))
            r.append('')

    io.open(RA, 'w', encoding='utf-8', newline='\n').write('\n'.join(r) + '\n')
    print('SINH XONG -> %s' % RA)
    print('  %d nhom · %d tham so' % (len(nhom), tong_input))
    print('  %d nhom rieng biet · %d khung gio (gop) · %d bo loc (gop)'
          % (len(con), len(kg), len(bl)))
    print('  dien giai viet tay da dan: %d / %d tham so' % (
        sum(1 for _, ds in nhom for t, _, _ in ds if t in dg), tong_input))
    return 0


if __name__ == '__main__':
    sys.exit(main())
