"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendProtocolCommand = sendProtocolCommand;
const protocolCommands_1 = require("./protocolCommands");
async function sendProtocolCommand(connection, commandName, args) {
    const command = protocolCommands_1.PROTOCOL_COMMANDS[commandName];
    if (!command) {
        throw new Error(`Unknown WebDriver command: ${commandName}`);
    }
    let path = command.path.replace(':sessionId', encodeURIComponent(connection.sessionId));
    command.variables.forEach((variable, index) => {
        path = path.replace(`:${variable}`, encodeURIComponent(String(args[index])));
    });
    if (path.includes(':')) {
        throw new Error(`Cannot build request for '${commandName}': unresolved path segment in '${path}'`);
    }
    const sendsBody = command.method !== 'GET' && command.method !== 'DELETE';
    const headers = { Accept: 'application/json' };
    const init = { method: command.method, headers };
    if (sendsBody) {
        headers['Content-Type'] = 'application/json';
        const body = {};
        command.parameters.forEach((parameter, index) => {
            body[parameter] = args[command.variables.length + index];
        });
        init.body = JSON.stringify(body);
    }
    const response = await fetch(`${connection.baseUrl}${path}`, init);
    const payload = await parseJsonBody(response);
    if (!response.ok) {
        throw new Error(extractErrorMessage(payload, commandName, response.status));
    }
    return unwrapValue(payload);
}
async function parseJsonBody(response) {
    const text = await response.text();
    if (!text) {
        return {};
    }
    try {
        return JSON.parse(text);
    }
    catch {
        return { value: text };
    }
}
function unwrapValue(payload) {
    if (payload && typeof payload === 'object' && 'value' in payload) {
        return payload.value;
    }
    return payload;
}
function extractErrorMessage(payload, commandName, status) {
    const value = unwrapValue(payload);
    const message = value?.message ?? value?.error;
    if (message) {
        return message;
    }
    return `WebDriver command '${commandName}' failed with status ${status}`;
}
