"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HelperAndroid = void 0;
const utils = __importStar(require("@applitools/utils"));
const gte_1 = __importDefault(require("semver/functions/gte"));
class HelperAndroid {
    static async make(options) {
        var _a;
        const { spec, driver } = options;
        let legacy = false;
        let input = await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelperEDT"]' });
        if (!input) {
            legacy = true;
            input = await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelper"]' });
        }
        const versionElement = await driver.element({
            type: 'xpath',
            selector: '//*[@content-desc="EyesAppiumHelper_Version"]',
        });
        const version = (_a = (await (versionElement === null || versionElement === void 0 ? void 0 : versionElement.getText()))) !== null && _a !== void 0 ? _a : '0.0.0';
        const action = !legacy
            ? await driver.element({ type: 'xpath', selector: '//*[@content-desc="EyesAppiumHelper_Action"]' })
            : null;
        return input
            ? new HelperAndroid({
                spec,
                driver,
                input,
                action,
                legacy,
                supportAsync: (0, gte_1.default)(version, '1.8.0'),
            })
            : null;
    }
    constructor(options) {
        this._supportAsync = false;
        this._spec = options.spec;
        this._driver = options.driver;
        this._input = options.input;
        this._action = options.action;
        this._legacy = options.legacy;
        this.name = this._legacy ? 'android-legacy' : 'android';
        this._supportAsync = options.supportAsync === true;
    }
    get logger() {
        return this._driver.logger;
    }
    async _getElementId(element) {
        const resourceId = await element.getAttribute('resource-id');
        if (!resourceId)
            return null;
        this.logger.log(`Helper library resource-id: ${resourceId}`);
        const result = resourceId.split('/');
        if (result.length === 1)
            return result[0];
        return result[1];
    }
    async _command(command) {
        await this._input.type(command);
        await this._input.click();
        let text = await this._input.getText();
        if (this._action && text === command) {
            await this._action.type('1').catch(() => null);
            text = await this._input.getText();
        }
        // wait until the JAVA complete the async operation
        const timeout = 5 * 60 * 1000;
        const finishAt = Date.now() + timeout;
        while (text === 'WAIT' && finishAt > Date.now()) {
            await utils.general.sleep(1000);
            text = await this._input.getText();
        }
        if (text === 'WAIT') {
            this.logger.warn(`Helper library didn't provide a response for async command (${command}) during ${timeout}ms`);
            text = '';
        }
        return text;
    }
    async getContentRegion(element, options) {
        var _a, _b, _c, _d, _e;
        const elementId = await this._getElementId(element);
        if (!elementId)
            return null;
        let contentHeightString;
        if (this._legacy) {
            await this._input.click();
            contentHeightString = await this._input.getText();
        }
        else if (this._supportAsync && ((_a = options === null || options === void 0 ? void 0 : options.lazyLoad) === null || _a === void 0 ? void 0 : _a.waitingTime)) {
            const result = await this._command(`offset_async;${elementId};0;0;0;${(_c = (_b = options === null || options === void 0 ? void 0 : options.lazyLoad) === null || _b === void 0 ? void 0 : _b.waitingTime) !== null && _c !== void 0 ? _c : 0}`);
            contentHeightString = result.split(';')[0];
        }
        else {
            contentHeightString = await this._command(`offset;${elementId};0;0;0;0`);
        }
        const contentHeight = Number(contentHeightString);
        if (Number.isNaN(contentHeight))
            return null;
        const region = await ((_e = (_d = this._spec).getElementRegion) === null || _e === void 0 ? void 0 : _e.call(_d, this._input.driver.target, element.target));
        if (!region || contentHeight < region.height)
            return null;
        return { x: region.x, y: region.y, width: region.width, height: contentHeight };
    }
    async getTouchPadding() {
        if (this._legacy)
            return undefined;
        const touchPaddingString = await this._command(`getTouchPadding;0;0;0;0;0`);
        const touchPadding = Number(touchPaddingString);
        if (!touchPadding || Number.isNaN(touchPadding))
            return undefined;
        return touchPadding;
    }
    async getRegion(element) {
        if (this._legacy)
            return null;
        const elementId = await this._getElementId(element);
        if (!elementId)
            return null;
        const regionString = await this._command(`getRect;${elementId};0;0;0`);
        if (!regionString)
            return null;
        const [, x, y, height, width] = regionString.match(/\[(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?);(-?\d+(?:\.\d+)?)\]/);
        const region = { x: Number(x), y: Number(y), width: Number(width), height: Number(height) };
        if (Number.isNaN(region.x + region.y + region.width + region.height))
            return null;
        return region;
    }
    async scrollToTop(element) {
        if (this._legacy)
            return;
        const elementId = await this._getElementId(element);
        if (!elementId)
            return;
        await this._command(`moveToTop;${elementId};0;-1;0`);
    }
    async scrollBy(element, offset) {
        if (this._legacy)
            return;
        const elementId = await this._getElementId(element);
        if (!elementId)
            return;
        await this._command(`scroll;${elementId};${offset.y};0;0;0`);
    }
}
exports.HelperAndroid = HelperAndroid;
