"""Server-side IBANgen example. No automatic retry, raw-input logging or account verification.

Set IBANGEN_API_KEY in the server environment. Premium metadata uses both API
and SWIFT credits. A timeout is indeterminate; review before repeating a chargeable
request. Never use this helper to assert account existence or payment acceptance.
"""
import json
import os
from urllib.error import HTTPError, URLError
from urllib.request import HTTPRedirectHandler, Request, build_opener


class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None  # Do not forward X-API-Key to a redirected host.


class PreflightUnavailable(RuntimeError):
    pass


def classify(results, expected_count):
    if not isinstance(results, list) or len(results) != expected_count:
        raise PreflightUnavailable('unexpected_response_shape')
    output = []
    for row in results:
        if not isinstance(row, dict) or type(row.get('valid')) is not bool:
            raise PreflightUnavailable('unexpected_validation_result')
        valid = row['valid']
        locked = bool(row.get('premium_fields_locked'))
        bic = row.get('swift_code')
        observed = isinstance(bic, str) and len(bic) in (8, 11) and bic.isalnum() and not locked
        output.append({
            'format_checksum': 'passed' if valid else 'failed',
            'bank_metadata': 'locked' if locked else ('observed' if valid and observed else 'unknown'),
            'account_existence': 'not_checked', 'account_ownership': 'not_checked',
            'payment_acceptance': 'not_checked',
        })
    return output


def preflight(ibans, api_key=None):
    if not isinstance(ibans, list) or not 1 <= len(ibans) <= 100:
        raise ValueError('provide_1_to_100_ibans')
    if any(not isinstance(value, str) or not value.strip() or len(value) > 64 for value in ibans):
        raise ValueError('invalid_input_shape')
    key = api_key or os.environ.get('IBANGEN_API_KEY')
    if not key:
        raise ValueError('server_api_key_required')
    request = Request('https://ibangen.com/api/v1/validate',
                      data=json.dumps({'ibans': ibans}).encode(), method='POST',
                      headers={'X-API-Key': key, 'Content-Type': 'application/json'})
    try:
        with build_opener(NoRedirect()).open(request, timeout=15) as response:
            payload = response.read(1024 * 1024 + 1)
            if len(payload) > 1024 * 1024:
                raise PreflightUnavailable('response_too_large')
            results = json.loads(payload)
    except HTTPError as error:
        raise PreflightUnavailable('validation_http_' + str(error.code)) from None
    except (URLError, TimeoutError, OSError, ValueError):
        raise PreflightUnavailable('validation_unavailable_do_not_auto_retry') from None
    return classify(results, len(ibans))
