"""Escaneo de puertos TCP habituales de cámaras/NVR."""
from __future__ import annotations

import socket
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Dict, Iterable, List, Optional, Tuple


DEFAULT_PORTS = [80, 443, 554, 8000, 8080, 8899, 37777, 37778, 8554]


def check_port(ip: str, port: int, timeout: float = 1.5) -> Tuple[int, bool, Optional[float]]:
    t0 = time.perf_counter()
    try:
        with socket.create_connection((ip, port), timeout=timeout):
            ms = (time.perf_counter() - t0) * 1000.0
            return port, True, ms
    except Exception:
        return port, False, None


def scan_ports(
    ip: str,
    ports: Optional[Iterable[int]] = None,
    timeout: float = 1.5,
    max_workers: int = 12,
) -> Dict[int, bool]:
    ports = list(ports or DEFAULT_PORTS)
    result: Dict[int, bool] = {}
    with ThreadPoolExecutor(max_workers=max_workers) as ex:
        futs = [ex.submit(check_port, ip, p, timeout) for p in ports]
        for fut in as_completed(futs):
            port, opened, _ = fut.result()
            result[port] = opened
    return result


def format_port_report(ip: str, ports: Dict[int, bool]) -> str:
    lines = [f"IP: {ip}", ""]
    for p in sorted(ports.keys()):
        state = "OPEN" if ports[p] else "CLOSED"
        lines.append(f"Puerto {p}: {state}")
    return "\n".join(lines)
