import { isIPv4, isIPv6 } from '@chainsafe/is-ip';
import { logger } from '@libp2p/logger';
import { DEVICE_INTERNET_GATEWAY_SERVICE_2, ONE_HOUR } from './constants.js';
import { Device } from './device.js';
import { discoverGateways } from './discovery.js';
import { fetchXML } from './fetch.js';
import { InternetGatewayService4 } from './internet-gateway-service-4.js';
import { InternetGatewayService6 } from './internet-gateway-service-6.js';
import { stripHostBrackets } from './utils.js';
const log = logger('nat-port-mapper:upnp');
export class UPnPClient {
    options;
    constructor(options = {}) {
        this.options = options;
    }
    async *findGateways(options) {
        log('find uPnP gateways');
        for await (const service of discoverGateways(options)) {
            const device = new Device(service);
            const host = stripHostBrackets(device.service.location.hostname);
            if (isIPv4(host)) {
                yield new InternetGatewayService4(device, this.options);
            }
            if (isIPv6(host)) {
                yield new InternetGatewayService6(device, this.options);
            }
        }
    }
    async getGateway(location, options = {}) {
        const descriptor = await fetchXML(location, options);
        const service = {
            location,
            details: descriptor,
            expires: Date.now() + ONE_HOUR,
            serviceType: descriptor.device.deviceType,
            uniqueServiceName: descriptor.device.UDN
        };
        const device = new Device(service);
        if (service.details.device.deviceType === DEVICE_INTERNET_GATEWAY_SERVICE_2) {
            if (isIPv4(location.hostname)) {
                return new InternetGatewayService4(device, this.options);
            }
            return new InternetGatewayService6(device, this.options);
        }
        throw new Error(`Device type was not "${DEVICE_INTERNET_GATEWAY_SERVICE_2}", it was "${service.details.device.deviceType}"`);
    }
}
//# sourceMappingURL=index.js.map