#!/usr/bin/env python3
# Создание структуры «Фото домов по объектам» на Диске Hram + копирование файлов кластеров
import json, os, time, urllib.request, urllib.parse
from concurrent.futures import ThreadPoolExecutor, as_completed

tok = None
for line in open("/root/site/yandex/.env_hram", encoding="utf-8"):
    if line.startswith("YANDEX2_ACCESS_TOKEN="):
        tok = line.split("=", 1)[1].strip()
H = {"Authorization": f"OAuth {tok}"}

def disk_mkdir(path):
    url = "https://cloud-api.yandex.net/v1/disk/resources?path=" + urllib.parse.quote(path)
    req = urllib.request.Request(url, method="PUT", headers=H)
    try:
        with urllib.request.urlopen(req, timeout=60) as r:
            return True
    except urllib.error.HTTPError as e:
        return "already" in e.read().decode(errors="replace")

def disk_upload_url(path, overwrite=True):
    url = ("https://cloud-api.yandex.net/v1/disk/resources/upload?path=" +
           urllib.parse.quote(path) + ("&overwrite=true" if overwrite else ""))
    req = urllib.request.Request(url, headers=H)
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.loads(r.read().decode())["href"]

def get_download_url(path):
    url = "https://cloud-api.yandex.net/v1/disk/resources/download?path=" + urllib.parse.quote(path)
    req = urllib.request.Request(url, headers=H)
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.loads(r.read().decode())["href"]

# структура: кластер -> имя папки
CLUSTER_DIRS = {
    1: "Владимирская область — стройка (каркас-кровля-отделка)",
    5: "Воскресенск — стройка каркасного дома",
    6: "Мытищи Тайнинское — дом клиента (Слезкин)",
    12: "Выставка Мытищи — съёмка с дрона",
    3: "Красногорск — планы и чертежи дома",
}
# C13 (1 фото, Воскресенск) добавим в C5
EXTRA_C13 = True

clusters = json.load(open("/root/site/video/clusters_geocoded.json", encoding="utf-8"))
cache = json.load(open("/root/site/video/gps_cache2.json", encoding="utf-8"))

ROOT = "/Фото домов по объектам"
disk_mkdir(ROOT)

jobs = []  # (src_path, dst_path)
for cl in clusters:
    cid = cl["cluster"]
    folder = CLUSTER_DIRS.get(cid)
    if not folder:
        continue
    if cid == 13:
        continue  # обработаем с C5
    d = f"{ROOT}/{folder}"
    disk_mkdir(d)
    for key in cl["keys"]:
        fname = cache[key]["name"]
        jobs.append((key, f"{d}/{fname}"))
        if cid == 5 and EXTRA_C13:
            pass  # C13 отдельно ниже

# C13 -> в папку Воскресенска
for cl in clusters:
    if cl["cluster"] == 13:
        d = f"{ROOT}/{CLUSTER_DIRS[5]}"
        disk_mkdir(d)
        for key in cl["keys"]:
            jobs.append((key, f"{d}/{cache[key]['name']}"))

print(f"Файлов к копированию: {len(jobs)}")

def work(job):
    src, dst = job
    try:
        # потоково: скачать -> загрузить
        href = get_download_url(src)
        up = disk_upload_url(dst)
        req = urllib.request.Request(href)
        with urllib.request.urlopen(req, timeout=180) as r:
            data = r.read()
        req2 = urllib.request.Request(up, data=data, method="PUT")
        with urllib.request.urlopen(req2, timeout=180) as r:
            st = r.status
        return (dst, st, len(data))
    except Exception as e:
        return (dst, -1, str(e)[:80])

t0 = time.time()
ok = 0
fail = []
with ThreadPoolExecutor(max_workers=4) as ex:
    futs = [ex.submit(work, j) for j in jobs]
    for i, fut in enumerate(as_completed(futs), 1):
        dst, st, info = fut.result()
        if st in (200, 201):
            ok += 1
        else:
            fail.append((dst, info))
        if i % 25 == 0:
            print(f"  {i}/{len(jobs)} | ok: {ok} | fail: {len(fail)} | {time.time()-t0:.0f}с")

print(f"\nГОТОВО: скопировано {ok}, ошибок {len(fail)}")
for d, e in fail[:10]:
    print("  FAIL:", d, e)
