import { isRouteMatchCondition } from "./router.js";
import { getImportUrlSourceForService } from "./worker-service-url.js";
import { getURLSource } from "./url.js";
export function getServiceBindingURL(input, service, config) {
    const source = getURLSource(input);
    if (source instanceof URL) {
        return source;
    }
    let base = getImportUrlSourceForService(service, config);
    if (base.startsWith("data:")) {
        base = "file:///";
    }
    return new URL(source, base);
}
export function createServiceBindingRouter({ config, service }, serviceWorker) {
    const protocolBindings = service.bindings?.filter(binding => binding.protocol);
    const nonProtocolBindings = service.bindings?.filter(binding => !binding.protocol);
    return (input, init) => {
        if (!service.bindings?.length) {
            return undefined;
        }
        try {
            const url = getServiceBindingURL(input, service, config);
            return (match(protocolBindings) ||
                match(nonProtocolBindings));
            function match(bindings) {
                for (const binding of bindings) {
                    if (isServiceMatchCondition(serviceWorker, config, service, binding, url, input, init)) {
                        return binding;
                    }
                }
                return undefined;
            }
        }
        catch (error) {
            console.error("Match error", error, input, service, config);
            return undefined;
        }
    };
}
function isServiceProtocolMatch(binding, url) {
    return (!binding.protocol ||
        binding.protocol === url.protocol ||
        (!binding.protocol.endsWith(":") &&
            `${binding.protocol}:` === url.protocol));
}
export function isServiceMatchCondition(serviceWorker, config, service, binding, url, input, init) {
    if (binding.protocol) {
        return isServiceProtocolMatch(binding, url);
    }
    if (binding.routes) {
        return isRoutesMatchCondition(serviceWorker, binding.routes, input, init);
    }
    if (binding.name) {
        return getServiceBindingURL(binding.name, service, config).toString() === url.toString();
    }
    return false;
}
function isRoutesMatchCondition(serviceWorker, routes, input, init) {
    if (Array.isArray(routes)) {
        for (const route of routes) {
            if (isRouteMatchCondition(serviceWorker.durable, route, input, init)) {
                return;
            }
        }
        return false;
    }
    else {
        return isRouteMatchCondition(serviceWorker.durable, routes, input, init);
    }
}
//# sourceMappingURL=service-router.js.map