# SPDX-License-Identifier: LSL-1.0
# Copyright (c) 2026 Markus Maiwald
# Stewardship: Self Sovereign Society Foundation
#
# This file is part of the Nexus Sovereign Core.
# See legal/LICENSE_SOVEREIGN.md for license terms.

## Fast Path Bypass (SPEC-700)
##
## Intercepts UTCP tunnel traffic (UDP/9999) before LwIP processing.
## Zero-copy header stripping via pointer arithmetic.

# Constants
const
  UTCP_TUNNEL_PORT* = 9999'u16
  ETHERTYPE_IPV4* = 0x0800'u16
  IPPROTO_UDP* = 17'u8
  
  # Header sizes
  ETH_HEADER_LEN* = 14
  IP_HEADER_LEN* = 20
  UDP_HEADER_LEN* = 8
  TUNNEL_OVERHEAD* = ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN  # 42 bytes
  
  # MTU safety
  MAX_UTCP_FRAME* = 1400'u16  # Safe for PPPoE/VPN

proc kprint(s: cstring) {.importc, cdecl.}
proc kprintln(s: cstring) {.importc, cdecl.}

# --- Fast Path Detection ---

proc is_utcp_tunnel*(data: ptr UncheckedArray[byte], len: uint16): bool {.exportc, cdecl.} =
  ## Check if packet is a UTCP tunnel packet (UDP port 9999)
  ## Returns true if packet should bypass LwIP
  
  # Minimum size check: ETH(14) + IP(20) + UDP(8) = 42 bytes
  if len < TUNNEL_OVERHEAD:
    return false
  
  # Check EtherType (big-endian at offset 12-13)
  let eth_type = (uint16(data[12]) shl 8) or uint16(data[13])
  if eth_type != ETHERTYPE_IPV4:
    return false
  
  # Check IP Protocol (offset 23 in frame = offset 9 in IP header)
  let ip_proto = data[23]
  if ip_proto != IPPROTO_UDP:
    return false
  
  # Check UDP destination port (big-endian at offset 36-37)
  # ETH(14) + IP(20) + UDP dst port offset(2) = 36
  let dst_port = (uint16(data[36]) shl 8) or uint16(data[37])
  
  return dst_port == UTCP_TUNNEL_PORT


proc strip_tunnel_headers*(data: ptr UncheckedArray[byte], len: var uint16): ptr UncheckedArray[byte] {.exportc, cdecl.} =
  ## Strip ETH+IP+UDP headers from tunnel packet (zero-copy)
  ## Returns pointer to UTCP header, adjusts length
  ## 
  ## SAFETY: Caller must ensure len >= TUNNEL_OVERHEAD
  
  if len < TUNNEL_OVERHEAD:
    return nil
  
  # Zero-copy: just advance pointer
  let utcp_data = cast[ptr UncheckedArray[byte]](
    cast[uint64](data) + TUNNEL_OVERHEAD
  )
  len = len - TUNNEL_OVERHEAD
  
  return utcp_data


proc check_mtu*(len: uint16): bool =
  ## Check if UTCP frame exceeds safe MTU
  return len <= MAX_UTCP_FRAME


# --- Source Address Extraction (for response routing) ---

type
  TunnelSource* = object
    ip*: uint32      # Source IP (network byte order)
    port*: uint16    # Source port

proc extract_tunnel_source*(data: ptr UncheckedArray[byte]): TunnelSource =
  ## Extract source IP and port from tunnel packet for response routing
  
  # Source IP at ETH(14) + IP src offset(12) = 26
  result.ip = (uint32(data[26]) shl 24) or 
              (uint32(data[27]) shl 16) or
              (uint32(data[28]) shl 8) or 
              uint32(data[29])
  
  # Source port at ETH(14) + IP(20) + UDP src offset(0) = 34
  result.port = (uint16(data[34]) shl 8) or uint16(data[35])
