import { CloudflareOptions, cloudflare } from "./cloudflare.js";

//#region src/index.d.ts
type Ipv4Tuple = [number, number, number, number];
type Ipv6Tuple = [number, number, number, number, number, number, number, number];
declare class Ipv4Cidr {
  type: "v4";
  partSize: 8;
  parts: Readonly<Ipv4Tuple>;
  bits: number;
  constructor(parts: Ipv4Tuple, bits: number);
  contains(ip: Array<number>): boolean;
}
declare class Ipv6Cidr {
  type: "v6";
  partSize: 16;
  parts: Readonly<Ipv6Tuple>;
  bits: number;
  constructor(parts: Ipv6Tuple, bits: number);
  contains(ip: Array<number>): boolean;
}
/**
* Parse CIDR addresses and keep non-CIDR IP addresses.
*
* @param value
*   Value to parse.
* @returns
*   Parsed {@linkcode Cidr} if range or given `value` if IP.
*/
declare function parseProxy(value: string): string | Cidr;
/**
* Parse a list of trusted proxies.
*
* CIDR range strings are parsed to {@linkcode Cidr} (so they match by range);
* plain IP strings and {@linkcode ProxyService} objects (such as those created
* by {@linkcode cloudflare}) are passed through unchanged. Use this to
* normalize the `proxies` option before handing it to {@linkcode findIp}.
*
* @param proxies
*   Trusted proxies to parse.
* @returns
*   Parsed proxies.
*/
declare function parseProxies(proxies: ReadonlyArray<string | ProxyService>): Array<string | Cidr | ProxyService>;
/**
* Socket-like interface.
*/
interface PartialSocket {
  remoteAddress?: string | null | undefined;
}
/**
* Interface that looks like info.
*/
interface PartialInfo {
  remoteAddress?: string | null | undefined;
}
interface PartialIdentiy {
  sourceIp?: string | null | undefined;
}
/**
* Interface that looks like a request context.
*/
interface PartialRequestContext {
  identity?: PartialIdentiy | null | undefined;
}
/**
* Interface with `headers`.
*/
type HeaderLike = {
  /**
  * Headers.
  */
  headers: Headers | Record<string, string[] | string | undefined>;
};
/**
* Interface that looks like a request,
* of which `headers` is required and several other fields may exist.
*/
type RequestLike = {
  /**
  * Some platforms pass `info`.
  */
  info?: PartialInfo | null | undefined;
  /**
  * Some platforms such as Cloudflare and Vercel provide `ip` directly on
  * `request`.
  */
  ip?: unknown;
  /**
  * Some platforms pass info in `requestContext`.
  */
  requestContext?: PartialRequestContext | null | undefined;
  /**
  * Some platforms pass a `socket`.
  */
  socket?: PartialSocket | null | undefined;
} & HeaderLike;
/**
* Platform name.
*/
type Platform = "cloudflare" | "firebase" | "fly-io" | "render" | "vercel";
/**
* Format of a client IP header set by a proxy service.
*
* - `"ip"` — a single IP address (e.g. `CF-Connecting-IP`).
* - `"ips"` — an `X-Forwarded-For`-style comma separated list, parsed
*   tail-to-head.
*/
type ClientIpFormat = "ip" | "ips";
/**
* A client IP header set by a proxy service.
*/
interface ClientIpHeader {
  /**
  * Header name (lower-case).
  */
  header: string;
  /**
  * How to parse the header value.
  */
  format: ClientIpFormat;
}
/**
* A trusted proxy service (such as Cloudflare) sitting in front of the
* application.
*
* Identified by IP range, with the header(s) that carry the real client IP.
* Create one with a helper such as {@linkcode cloudflare} and include it in the
* `proxies` array.
*/
interface ProxyService {
  /**
  * Discriminant marking this entry as a proxy service.
  */
  kind: "service";
  /**
  * Name of the service (such as `"cloudflare"`).
  */
  name: string;
  /**
  * IP addresses and CIDR ranges that identify this service.
  */
  ranges: ReadonlyArray<string | Cidr>;
  /**
  * Header(s) this service uses to relay the real client IP, in priority order.
  */
  clientIp: ReadonlyArray<ClientIpHeader>;
}
/**
* Configuration.
*/
interface Options {
  /**
  * Platform the code is running on;
  * used to allow only known more trustworthy headers.
  */
  platform?: Platform | null | undefined;
  /**
  * Trusted proxies.
  *
  * IP addresses and CIDR ranges are treated as trusted load balancers or
  * proxies and skipped when finding the client IP. Proxy services created with
  * a helper such as {@linkcode cloudflare} additionally declare which header
  * carries the real client IP.
  */
  proxies?: ReadonlyArray<string | Cidr | ProxyService> | null | undefined;
}
/**
* Find a client IP address on a request-like object.
*
* @param request
*   Request-like object.
* @param [options]
*   Configuration (optional).
* @returns
*   Found IP address; empty string if not found.
*/
declare function findIp(request: RequestLike, options?: Options | null | undefined): string;
/**
* One of the CIDR ranges.
*/
type Cidr = Ipv4Cidr | Ipv6Cidr;
//#endregion
export { Cidr, ClientIpFormat, ClientIpHeader, type CloudflareOptions, HeaderLike, Options, Platform, ProxyService, RequestLike, cloudflare, findIp as default, findIp, parseProxies, parseProxy };