"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.backToDefaultKeyboardKeyFindInfo = exports.shiftKeyFindInfo = exports.symbolsKeyFindInfo = exports.numbersKeyFindInfo = exports.charFindInfo = exports.AppleKeyboardState = void 0;
exports.getFindInfoForKey = getFindInfoForKey;
exports.isInNumbersKeyboard = isInNumbersKeyboard;
exports.isInSymbolsKeyboard = isInSymbolsKeyboard;
exports.createFindsForiOSTextEntryByKeyboard = createFindsForiOSTextEntryByKeyboard;
exports.findElementByPredicate = findElementByPredicate;
exports.sendKeysThroughNativeiOSKeyboard = sendKeysThroughNativeiOSKeyboard;
var AppleKeyboardState;
(function (AppleKeyboardState) {
    AppleKeyboardState["DEFAULT"] = "default";
    AppleKeyboardState["NUMBERS"] = "numbers";
    AppleKeyboardState["SYMBOLS"] = "symbols";
})(AppleKeyboardState || (exports.AppleKeyboardState = AppleKeyboardState = {}));
function getFindInfoForKey(name, label, buttonType) {
    const type = buttonType ?? 'XCUIElementTypeKey';
    return {
        name,
        label,
        type,
    };
}
const charFindInfo = (char) => getFindInfoForKey(char, char);
exports.charFindInfo = charFindInfo;
const numbersKeyFindInfo = () => getFindInfoForKey('more', 'numbers', 'XCUIElementTypeKey');
exports.numbersKeyFindInfo = numbersKeyFindInfo;
const symbolsKeyFindInfo = () => getFindInfoForKey('shift', 'symbols', 'XCUIElementTypeButton');
exports.symbolsKeyFindInfo = symbolsKeyFindInfo;
const shiftKeyFindInfo = () => getFindInfoForKey('shift', 'shift', 'XCUIElementTypeButton');
exports.shiftKeyFindInfo = shiftKeyFindInfo;
const backToDefaultKeyboardKeyFindInfo = () => getFindInfoForKey('more', 'letters', 'XCUIElementTypeButton');
exports.backToDefaultKeyboardKeyFindInfo = backToDefaultKeyboardKeyFindInfo;
function isInNumbersKeyboard(char) {
    return [
        '1',
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        '0',
        '-',
        '/',
        ':',
        ';',
        '(',
        ')',
        '$',
        '&',
        '@',
        '"',
        '.',
        ',',
        '?',
        '!',
        "'",
    ].includes(char);
}
function isInSymbolsKeyboard(char) {
    return [
        ']',
        '[',
        '{',
        '}',
        '#',
        '%',
        '^',
        '*',
        '+',
        '=',
        '_',
        '\\',
        '|',
        '~',
        '<',
        '>',
        '€',
        '£',
        '¥',
        '•',
    ].includes(char);
}
function getTransitionFindsForKeyboardState(currentState, desiredState) {
    const findChain = [];
    switch (desiredState) {
        case AppleKeyboardState.DEFAULT: {
            if (currentState === AppleKeyboardState.NUMBERS ||
                currentState === AppleKeyboardState.SYMBOLS) {
                findChain.push((0, exports.backToDefaultKeyboardKeyFindInfo)());
            }
            break;
        }
        case AppleKeyboardState.NUMBERS: {
            if (currentState === AppleKeyboardState.DEFAULT) {
                findChain.push((0, exports.numbersKeyFindInfo)());
            }
            else if (currentState === AppleKeyboardState.SYMBOLS) {
                findChain.push((0, exports.backToDefaultKeyboardKeyFindInfo)());
                findChain.push((0, exports.numbersKeyFindInfo)());
            }
            break;
        }
        case AppleKeyboardState.SYMBOLS: {
            if (currentState === AppleKeyboardState.DEFAULT) {
                findChain.push((0, exports.numbersKeyFindInfo)());
                findChain.push((0, exports.symbolsKeyFindInfo)());
            }
            else if (currentState === AppleKeyboardState.NUMBERS) {
                findChain.push((0, exports.symbolsKeyFindInfo)());
            }
        }
    }
    return findChain;
}
function createFindsForiOSTextEntryByKeyboard(text, initialKeyboardState = AppleKeyboardState.DEFAULT) {
    const characters = text.split('');
    const findChain = [];
    let keyboardState = initialKeyboardState;
    for (const char of characters) {
        if (char === ' ') {
            findChain.push((0, exports.charFindInfo)('space'));
            keyboardState = AppleKeyboardState.DEFAULT;
        }
        else if (isInNumbersKeyboard(char)) {
            findChain.push(...getTransitionFindsForKeyboardState(keyboardState, AppleKeyboardState.NUMBERS));
            keyboardState = AppleKeyboardState.NUMBERS;
            findChain.push((0, exports.charFindInfo)(char));
        }
        else if (isInSymbolsKeyboard(char)) {
            findChain.push(...getTransitionFindsForKeyboardState(keyboardState, AppleKeyboardState.SYMBOLS));
            keyboardState = AppleKeyboardState.SYMBOLS;
            findChain.push((0, exports.charFindInfo)(char));
        }
        else {
            findChain.push(...getTransitionFindsForKeyboardState(keyboardState, AppleKeyboardState.DEFAULT));
            keyboardState = AppleKeyboardState.DEFAULT;
            const isLowercase = char === char.toLowerCase();
            if (!isLowercase) {
                findChain.push((0, exports.shiftKeyFindInfo)());
            }
            findChain.push((0, exports.charFindInfo)(char));
        }
    }
    return findChain;
}
function findElementByPredicate(driver, name, label, type) {
    return driver
        .$(`-ios predicate string:name == "${name}" && label == "${label}" && type == "${type}"`)
        .getElement();
}
async function getKeyboardState(driver) {
    const foundNumber = await findElementByPredicate(driver, '9', '9', 'XCUIElementTypeKey');
    if (foundNumber.error) {
        return AppleKeyboardState.DEFAULT;
    }
    return AppleKeyboardState.NUMBERS;
}
async function sendKeysThroughNativeiOSKeyboard(driver, text) {
    const initialKeyboardState = await getKeyboardState(driver);
    const findChain = createFindsForiOSTextEntryByKeyboard(text, initialKeyboardState);
    let isShiftPressed = false;
    const foundCapital = await findElementByPredicate(driver, 'M', 'M', 'XCUIElementTypeKey');
    isShiftPressed = !foundCapital.error;
    if (isShiftPressed && findChain[0].label === 'shift') {
        findChain.shift();
    }
    if (text.length >= 0 &&
        text[0] !== ' ' &&
        text[0].toLowerCase() === text[0]) {
        if (isShiftPressed) {
            const shiftKey = await findElementByPredicate(driver, 'shift', 'shift', 'XCUIElementTypeButton');
            await shiftKey.click();
        }
    }
    for (const find of findChain) {
        const key = await findElementByPredicate(driver, find.name, find.label, find.type);
        await key.click();
    }
}
