"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NavigationPage = void 0;
const test_1 = require("@playwright/test");
const LoginPage_1 = require("./LoginPage");
const sleep_1 = require("../../utils/sleep");
const constants_1 = require("../../utils/constants");
const env_1 = require("../../utils/env");
const ORCHESTRATION_CONTEXT_PATH = process.env.ORCHESTRATION_CONTEXT_PATH ?? '/orchestration';
const NORMALIZED_ORCHESTRATION_CONTEXT_PATH = ORCHESTRATION_CONTEXT_PATH.startsWith('/')
    ? ORCHESTRATION_CONTEXT_PATH
    : `/${ORCHESTRATION_CONTEXT_PATH}`;
const MODELER_CONTEXT_PATH = process.env.MODELER_CONTEXT_PATH ?? '/modeler';
const OPTIMIZE_CONTEXT_PATH = process.env.OPTIMIZE_CONTEXT_PATH ?? '/optimize';
const CONSOLE_CONTEXT_PATH = process.env.CONSOLE_CONTEXT_PATH ?? '/console';
const MANAGEMENT_IDENTITY_CONTEXT_PATH = process.env.MANAGEMENT_IDENTITY_CONTEXT_PATH ?? '/identity';
const IDENTITY_FIRSTUSER_USERNAME = process.env.DISTRO_QA_E2E_TESTS_IDENTITY_FIRSTUSER_USERNAME || 'demo';
const IDENTITY_FIRSTUSER_PASSWORD = process.env.DISTRO_QA_E2E_TESTS_IDENTITY_FIRSTUSER_PASSWORD || 'demo';
class NavigationPage {
    page;
    modelerPageBanner;
    operatePageBanner;
    tasklistPageBanner;
    optimizePageBanner;
    identityPageBanner;
    consolePageBanner;
    keyboardPageBanner;
    managementIdentityPageBanner;
    constructor(page) {
        this.page = page;
        this.operatePageBanner = page.getByRole('link', {
            name: 'Camunda logo Operate',
        });
        this.modelerPageBanner = page
            .locator('a')
            .filter({ hasText: 'Camunda logoModeler' });
        this.tasklistPageBanner = page.getByRole('link', {
            name: 'Camunda logo Tasklist',
        });
        this.optimizePageBanner = page.getByRole('link', {
            name: 'Camunda logo Optimize',
        });
        // TODO: Drop support for Identity once we fully rename it to Admin
        this.identityPageBanner = page
            .locator('a')
            .filter({ hasText: /^Camunda logo\s*(Identity|Admin)$/ })
            .first();
        this.consolePageBanner = page.getByRole('link', {
            name: 'Camunda logo Console',
        });
        this.managementIdentityPageBanner = page
            .locator('a')
            .filter({ hasText: /^Camunda logo\s*Management Identity$/ })
            .first();
        this.keyboardPageBanner = page.locator('#keycloak-bg');
    }
    async goTo(url, banner, sleepTimeout, { username = IDENTITY_FIRSTUSER_USERNAME, password = IDENTITY_FIRSTUSER_PASSWORD, } = {}, maxRetries = 5) {
        const startTime = Date.now();
        let timeout = constants_1._1_SECOND_IN_MS * 10;
        if (url === '/modeler') {
            timeout = constants_1._1_SECOND_IN_MS * 20;
        }
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            try {
                if (sleepTimeout) {
                    await (0, sleep_1.sleep)(sleepTimeout);
                }
                await this.page.goto(url, {
                    timeout: 60000,
                    waitUntil: 'domcontentloaded',
                });
                const loginPage = new LoginPage_1.LoginPage(this.page);
                const loginEntryPoint = banner
                    .or(loginPage.usernameInput)
                    .or(loginPage.coreUsernameInput)
                    .or(loginPage.keycloakBanner)
                    .first();
                await (0, test_1.expect)(loginEntryPoint).toBeVisible({ timeout: 60000 });
                const isBannerVisible = await banner.isVisible().catch(() => false);
                if (isBannerVisible) {
                    const loginVisible = await loginPage.usernameInput.isVisible();
                    if (loginVisible) {
                        await loginPage.login(username, password);
                    }
                    // If login selector not visible, banner is real - navigation succeeded
                }
                else {
                    await loginPage.login(username, password);
                }
                await (0, test_1.expect)(banner).toBeVisible({ timeout: 60000 });
                return;
            }
            catch (error) {
                const now = new Date();
                const elapsed = Date.now() - startTime;
                if (attempt < maxRetries - 1) {
                    await (0, sleep_1.sleep)(2000);
                    if (!this.page.isClosed()) {
                        try {
                            await this.page.waitForLoadState('load', { timeout: timeout });
                        }
                        catch (error) {
                            const now2 = new Date();
                            const elapsed2 = Date.now() - startTime;
                            console.warn(`[${now2.toISOString()}] (+${elapsed2}ms) [NavigationPage] Load state timeout or error: ${error}`);
                        }
                    }
                }
                else {
                    console.error(`[${now.toISOString()}] (+${elapsed}ms) [NavigationPage] Login (${url}) failed after ${maxRetries} attempts`);
                    throw new Error(`Login (${url}) failed after ${maxRetries} attempts`);
                }
            }
        }
    }
    async goToModeler(sleepTimeout, credentials) {
        await this.goTo(MODELER_CONTEXT_PATH, this.modelerPageBanner, sleepTimeout, credentials);
    }
    async goToTasklist(sleepTimeout, credentials) {
        await this.goTo(`${NORMALIZED_ORCHESTRATION_CONTEXT_PATH}/tasklist`, this.tasklistPageBanner, sleepTimeout, credentials);
    }
    async goToOperate(sleepTimeout, credentials) {
        await this.goTo(`${NORMALIZED_ORCHESTRATION_CONTEXT_PATH}/operate`, this.operatePageBanner, sleepTimeout, credentials);
    }
    async goToOptimize(sleepTimeout, credentials) {
        await this.goTo(OPTIMIZE_CONTEXT_PATH, this.optimizePageBanner, sleepTimeout, credentials);
    }
    async goToKeycloak(maxRetries = 5) {
        const keycloakUrl = process.env.KEYCLOAK_URL
            ? `${process.env.KEYCLOAK_URL}/auth`
            : '/auth';
        let lastError;
        for (let attempt = 0; attempt < maxRetries; attempt++) {
            try {
                await this.page.goto(keycloakUrl);
                await (0, test_1.expect)(this.keyboardPageBanner).toBeVisible({ timeout: 60000 });
                return;
            }
            catch (error) {
                lastError = error;
                if (attempt < maxRetries - 1) {
                    await (0, sleep_1.sleep)(5000);
                }
            }
        }
        throw lastError instanceof Error
            ? lastError
            : new Error(`goToKeycloak failed after ${maxRetries} attempts`);
    }
    async goToOCAdmin(sleepTimeout, credentials) {
        await this.goTo(`${NORMALIZED_ORCHESTRATION_CONTEXT_PATH}/admin`, this.identityPageBanner, sleepTimeout, credentials, env_1.isOpenSearch ? 10 : 5);
    }
    async goToConsole(sleepTimeout, credentials) {
        await this.goTo(CONSOLE_CONTEXT_PATH, this.consolePageBanner, sleepTimeout, credentials);
    }
    async goToManagementIdentity(sleepTimeout, credentials) {
        await this.goTo(MANAGEMENT_IDENTITY_CONTEXT_PATH, this.managementIdentityPageBanner, sleepTimeout, credentials);
    }
}
exports.NavigationPage = NavigationPage;
