#!/usr/bin/env python3
"""Пошук судових рішень у CENDOJ (poderjudicial.es) з командного рядка.

База містить рішення всіх іспанських судів (TS, AN, TSJ, AP...). Вебформа
не має API, але бекенд search.action приймає звичайний POST — головне
представлятися браузером (WAF ріже "голі" запити) і мати cookie сесії.
Транспорт — через curl: системний Python на macOS не має сертифікатів.

Приклади:
    python3 scripts/cendoj.py '"protección temporal" ucraniana'
    python3 scripts/cendoj.py 'arraigo ucraniano' --pages 3
    python3 scripts/cendoj.py '"protección temporal" Ucrania' --download out/

Вивід — TSV: назва (з ROJ і датою), сторінка документа, пряме посилання
на PDF. З --download PDF-и складаються в теку, і поруч кладеться .txt
(якщо встановлено pdftotext).
"""
import argparse
import html
import pathlib
import re
import subprocess
import sys
import tempfile
import time

BASE = 'https://www.poderjudicial.es'
UA = ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 '
      '(KHTML, like Gecko) Chrome/126.0 Safari/537.36')

DOC_RE = re.compile(
    r'<a [^>]*href="(https://www\.poderjudicial\.es/search/AN/openDocument/'
    r'([0-9a-f]+)/(\d+))"[^>]*>\s*([^<]{5,250})')
TOTAL_RE = re.compile(r'([\d.]+)\s*resultados?')


def curl(jar, url, *extra, out=None):
    cmd = ['curl', '-s', '-A', UA, '-b', jar, '-c', jar,
           '-e', f'{BASE}/search/indexAN.jsp', *extra, url]
    if out:
        cmd += ['-o', str(out)]
        subprocess.run(cmd, check=True, timeout=90)
        return b''
    return subprocess.run(cmd, check=True, timeout=90,
                          capture_output=True).stdout


def search(jar, query, page):
    """Одна сторінка результатів: 10 документів, від найновіших."""
    form = [
        ('action', 'query'),
        ('sort', 'IN_FECHARESOLUCION:decreasing'),
        ('recordsPerPage', '10'),
        ('databasematch', 'AN'),
        ('start', str((page - 1) * 10 + 1)),
        ('TEXT', query),
    ]
    extra = []
    for k, v in form:
        extra += ['--data-urlencode', f'{k}={v}']
    body = curl(jar, f'{BASE}/search/search.action', *extra).decode('utf-8', 'replace')
    total = TOTAL_RE.search(body)
    items = []
    for url, ref, opt, title in DOC_RE.findall(re.sub(r'\s+', ' ', body)):
        pdf = (f'{BASE}/search/contenidos.action?action=accessToPDF'
               f'&publicinterface=true&tab=AN&reference={ref}'
               f'&encode=true&optimize={opt}&databasematch=AN')
        items.append((html.unescape(title).strip(), url, pdf))
    return (total.group(1) if total else '?'), items


def main():
    ap = argparse.ArgumentParser(description=__doc__.split('\n')[0])
    ap.add_argument('query', help='повнотекстовий запит (лапки — точна фраза)')
    ap.add_argument('--pages', type=int, default=1, help='скільки сторінок по 10 (типово 1)')
    ap.add_argument('--download', metavar='DIR', help='скачати PDF-и в теку й витягти текст')
    args = ap.parse_args()

    with tempfile.TemporaryDirectory() as tmp:
        jar = f'{tmp}/cookies.txt'
        curl(jar, f'{BASE}/search/indexAN.jsp')  # отримуємо cookie сесії

        seen = 0
        for page in range(1, args.pages + 1):
            total, items = search(jar, args.query, page)
            if page == 1:
                print(f'# всього результатів: {total}', file=sys.stderr)
            if not items:
                break
            for title, url, pdf in items:
                print(f'{title}\t{url}\t{pdf}')
                if args.download:
                    out = pathlib.Path(args.download)
                    out.mkdir(parents=True, exist_ok=True)
                    roj = re.search(r'ROJ:\s*(.+)$', title)
                    name = re.sub(r'[^\w-]+', '_', roj.group(1) if roj else title)[:60]
                    dest = out / f'{name}.pdf'
                    if not dest.exists():
                        curl(jar, pdf, out=dest)
                        subprocess.run(
                            ['pdftotext', '-layout', dest, dest.with_suffix('.txt')],
                            check=False)
                        time.sleep(1)  # не заваджуємо серверу
            seen += len(items)
            if page < args.pages:
                time.sleep(1)
        print(f'# отримано: {seen}', file=sys.stderr)


if __name__ == '__main__':
    main()
