"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenEmailExecutor = void 0;
exports.openUrlInDeviceBrowser = openUrlInDeviceBrowser;
exports.maybeInitializeChromeOnAndroid = maybeInitializeChromeOnAndroid;
exports.android13ChromeInit = android13ChromeInit;
exports.androidChromeInit = androidChromeInit;
exports.waitForSelector = waitForSelector;
const sleep_1 = require("@mablhq-internal/runtime/util/sleep");
const mablApi_1 = require("@mablhq-internal/runtime/mablApi");
const execution_1 = require("@mablhq-internal/runtime/execution");
const execution_2 = require("@mablhq-internal/runtime/execution");
const OpenLinkExecutor_1 = require("./OpenLinkExecutor");
const async_retry_1 = __importDefault(require("async-retry"));
class OpenEmailExecutor {
    async run(step, executionContext) {
        await executionContext.observeDeferredFunction();
        const findDescriptor = {
            type: 'email',
            selector: step.find.findTarget.selector,
            configuration: step.configuration,
        };
        const matchedEmail = await execution_2.FindEmail.run(findDescriptor, executionContext);
        if (!matchedEmail) {
            return {
                status: execution_1.StepStatus.Failed,
                logInfo: 'Failed to find target email. Make sure email match criteria is configured correctly.',
            };
        }
        const emailUrl = matchedEmail.input_artifacts?.body_html_uri ||
            matchedEmail.input_artifacts?.body_text_uri;
        if (!emailUrl) {
            return {
                status: execution_1.StepStatus.Failed,
                logInfo: 'Failed to find email URL',
            };
        }
        try {
            await openUrlInDeviceBrowser(emailUrl, executionContext);
        }
        catch (error) {
            executionContext.log.error(error);
            return {
                status: execution_1.StepStatus.Failed,
                logInfo: 'Failed to open email URL',
            };
        }
        return { status: execution_1.StepStatus.Passed };
    }
}
exports.OpenEmailExecutor = OpenEmailExecutor;
async function openUrlInDeviceBrowser(url, executionContext) {
    const platform = executionContext.mobileTestEnvironment.getConfig().app.platformName;
    const driver = executionContext.mobileTestEnvironment.getDriver();
    const platformVersion = executionContext.mobileTestEnvironment.getConfig().app.platformVersion;
    switch (platform) {
        case mablApi_1.MobilePlatformEnum.Android:
            await (0, OpenLinkExecutor_1.openDeepLink)(url, 'com.android.chrome', driver, platform, platformVersion);
            if (!executionContext.chromeInitHasOcurred) {
                try {
                    await maybeInitializeChromeOnAndroid(driver);
                    executionContext.chromeInitHasOcurred = true;
                }
                catch (error) {
                    executionContext.log.warning(`Unable to attempt to auto initialize Chrome: ${error}`);
                }
            }
            return;
        case mablApi_1.MobilePlatformEnum.Ios:
            return (0, OpenLinkExecutor_1.openDeepLink)(url, 'com.apple.mobilesafari', driver, platform, platformVersion);
    }
}
const MAX_CHROME_INIT_ELEMENT_RETRY_TIME_MILLIS = 5_000;
async function maybeInitializeChromeOnAndroid(driver) {
    await (0, sleep_1.sleep)(2_000);
    const deviceInfo = await driver.execute('mobile: deviceInfo');
    switch (deviceInfo?.platformVersion) {
        case '13': {
            await android13ChromeInit(driver);
            return;
        }
        default:
            await androidChromeInit(driver);
    }
}
async function android13ChromeInit(driver) {
    const updatedInitWorkflow = await driver
        .$(`android=new UiSelector().text("Use without an account").className("android.widget.Button")`)
        .getElement();
    if (updatedInitWorkflow.elementId) {
        return androidChromeInit(driver);
    }
    const button = await waitForSelector(driver, `android=new UiSelector().text("Accept & continue").className("android.widget.Button")`, MAX_CHROME_INIT_ELEMENT_RETRY_TIME_MILLIS);
    await button.click();
    const noThanksButtonSelector = `android=new UiSelector().text("No thanks").className("android.widget.Button")`;
    const noThanksButtonOne = await waitForSelector(driver, noThanksButtonSelector, MAX_CHROME_INIT_ELEMENT_RETRY_TIME_MILLIS);
    await noThanksButtonOne.click();
    const noThanksButtonTwo = await waitForSelector(driver, noThanksButtonSelector, MAX_CHROME_INIT_ELEMENT_RETRY_TIME_MILLIS);
    await noThanksButtonTwo.click();
}
async function androidChromeInit(driver) {
    const button = await waitForSelector(driver, `android=new UiSelector().text("Use without an account").className("android.widget.Button")`, MAX_CHROME_INIT_ELEMENT_RETRY_TIME_MILLIS);
    await button.click();
    const notThanksButton = await waitForSelector(driver, `android=new UiSelector().text("No thanks").className("android.widget.Button")`, MAX_CHROME_INIT_ELEMENT_RETRY_TIME_MILLIS);
    await notThanksButton.click();
    return;
}
function waitForSelector(driver, selector, maxRetryTimeMillis) {
    return (0, async_retry_1.default)(async () => {
        const element = await driver.$(selector).getElement();
        if (!element.elementId) {
            throw new Error('Element not found');
        }
        return element;
    }, {
        retries: 10,
        minTimeout: 500,
        maxTimeout: 5_000,
        maxRetryTime: maxRetryTimeMillis,
    });
}
