PAYMENT_PATTERNS = ['/payment', '/checkout', '/billing', '/stripe', '/invoice', '/card', '/refund']


def is_payment_route(route: str) -> bool:
    r = route.lower()
    return any(p in r for p in PAYMENT_PATTERNS)


def sanitize_span(span: dict) -> dict:
    """
    Final redaction pass before any data leaves the customer's machine.
    Operates on a copy — never mutates the input.
    """
    span = dict(span)
    attrs = dict(span.get('attributes', {}))

    route = attrs.get('http.route', attrs.get('http_route', ''))
    if is_payment_route(route):
        attrs = {
            'http.route': '[PAYMENT ENDPOINT]',
            'http.method': attrs.get('http.method', ''),
            'http.status_code': attrs.get('http.status_code', 0),
            'db_queries': [],
            'outbound_calls': [],
            'error': None,
        }

    # Strip query values — keep only normalized SQL structure
    db_queries = []
    for q in attrs.get('db_queries', []):
        db_queries.append({
            'query_hash': q.get('query_hash', ''),
            'normalized_sql': q.get('normalized_sql', ''),
            'duration_ms': q.get('duration_ms', 0),
            'rows_examined': q.get('rows_examined', 0),
            'db_driver': q.get('db_driver', 'unknown'),
        })
    attrs['db_queries'] = db_queries

    # Strip outbound response bodies — host + path + timing only
    outbound = []
    for c in attrs.get('outbound_calls', []):
        outbound.append({
            'host': c.get('host', ''),
            'path': c.get('path', ''),
            'method': c.get('method', 'GET'),
            'status_code': c.get('status_code', 0),
            'duration_ms': c.get('duration_ms', 0),
        })
    attrs['outbound_calls'] = outbound

    # Strip variable values from error — keep file + line only
    error = attrs.get('error')
    if error:
        attrs['error'] = {
            'error_type': error.get('error_type', ''),
            'error_file': error.get('error_file', ''),
            'error_line': error.get('error_line'),
            'stack_frames': [
                {'file': f.get('file', ''), 'line': f.get('line'), 'function': f.get('function', '')}
                for f in error.get('stack_frames', [])
            ],
        }

    span['attributes'] = attrs
    return span
