#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Доставка icd-macro-model в топик-Хранилище (10031) через Bot API.
Токен из ~/.hermes/.env, не печатается. Прокси 127.0.0.1:3128. Верификация ok:true+file_size."""
import json, urllib.request, urllib.parse, os, uuid

CHAT_ID = "-1003973539149"; THREAD = 10031
ARCHIVE = "/home/matvey/projects/icd-macro-model/dist/icd_macro_model_20261103.tar.gz"
SHA = "fa1599de8339ac43a5b96e2b71778b08d7df5df21e20dddce69413a2a88f7826"
PROXY = "http://127.0.0.1:3128"

tok = None
for line in open(os.path.expanduser("~/.hermes/.env")):
    line = line.strip()
    if line.startswith("TELEGRAM_BOT_TOKEN="):
        tok = line.split("=", 1)[1].strip().strip('"').strip("'"); break
assert tok, "токен не найден"
print(f"токен: len={len(tok)}")

opener = urllib.request.build_opener(urllib.request.ProxyHandler({"https": PROXY, "http": PROXY}))

def api(method, data=None, files=None, timeout=120):
    url = f"https://api.telegram.org/bot{tok}/{method}"
    if files:
        boundary = uuid.uuid4().hex
        body = b""
        for k, v in (data or {}).items():
            body += f'--{boundary}\r\nContent-Disposition: form-data; name="{k}"\r\n\r\n{v}\r\n'.encode()
        for k, path in files.items():
            fn = os.path.basename(path)
            body += f'--{boundary}\r\nContent-Disposition: form-data; name="{k}"; filename="{fn}"\r\nContent-Type: application/octet-stream\r\n\r\n'.encode()
            body += open(path, "rb").read() + b"\r\n"
        body += f"--{boundary}--\r\n".encode()
        req = urllib.request.Request(url, data=body, method="POST",
            headers={"Content-Type": f"multipart/form-data; boundary={boundary}"})
    else:
        req = urllib.request.Request(url, data=urllib.parse.urlencode(data or {}).encode(), method="POST")
    r = opener.open(req, timeout=timeout)
    return json.loads(r.read())

msg = (
    "📦 Макро-модель управления процессами ИЦД + записка ЭС-2050 — архив комплекта · 03.11.2026\n\n"
    "Основание: Энергостратегия-2050 (распоряжение 908-р) — цифровой двойник отрасли → управляемая автономия.\n\n"
    "В архиве (171 КБ, tar.gz, sha256 fa1599…7826):\n"
    "• Записка_ЦД_отрасли_ЭС2050_для_обсуждения.docx — записка для обсуждения в компании (ЭС-2050 → двойники → агенты → зоны готовности → рамка → эффекты → дорожная карта года → вопросы)\n"
    "• model_v1.1.pdf — макро-модель v1.1 (5 стр.): архитектура с контуром доверия, лестница «данные × автономия × риск», десять законов как гейты, роли по 187-ФЗ\n"
    "• model_v1.1.html + gen_zapiska.py — исходники для правок\n"
    "• ПЗ.md, MANIFEST.md\n\n"
    "v1.1 включает правки тройного аудита (скептический/правовой/инженерный). Документы обезличены."
)
r1 = api("sendMessage", {"chat_id": CHAT_ID, "message_thread_id": THREAD, "text": msg})
print("описание:", r1.get("ok"), "msg_id:", r1.get("result", {}).get("message_id"))

r2 = api("sendDocument", {"chat_id": CHAT_ID, "message_thread_id": THREAD,
    "caption": "icd_macro_model_20261103.tar.gz · sha256 fa1599de8339ac43a5b96e2b71778b08d7df5df21e20dddce69413a2a88f7826"},
    files={"document": ARCHIVE})
ok = r2.get("ok"); doc = r2.get("result", {}).get("document", {})
print("документ:", ok, "| file_size:", doc.get("file_size"), "| file_name:", doc.get("file_name"))
size_local = os.path.getsize(ARCHIVE)
assert ok and doc.get("file_size") == size_local, "РАЗМЕР НЕ СХОДИТСЯ"
print(f"ВЕРИФИКАЦИЯ: ok=true, file_size {doc['file_size']} == {size_local} байт ✅")
