"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClusterPage = void 0;
const test_1 = require("@playwright/test");
const sleep_1 = require("../../utils/sleep");
const clickLocatorWithRetry_1 = require("../../utils/assertionHelpers/clickLocatorWithRetry");
const expectLocatorWithRetry_1 = require("../../utils/assertionHelpers/expectLocatorWithRetry");
class ClusterPage {
    defaultClusterType = 'G3-Dev';
    page;
    createNewClusterButton;
    clusterNameInput;
    createClusterButton;
    clusterCreatingStatusText;
    clusterHealthyStatusText;
    clusterHealthyIndicatorSelector;
    clusterGenerationCompleteMessage;
    clustersBreadcrumb;
    deleteClusterButton;
    confirmDeleteInput;
    dangerDeleteButton;
    connectorSecretsTab;
    createAClusterButton;
    clusterVersionOption;
    alphaTab;
    devTab;
    stableTab;
    qaGenerationsTab;
    gcpRegion;
    belgiumRegion;
    finlandRegion;
    londonRegion;
    g3DevClusterType;
    clustersList;
    cluster;
    clusterHealthiness;
    clusterLink;
    clusterDeleteButton;
    dialog;
    constructor(page) {
        this.page = page;
        this.dialog = page.getByRole('dialog');
        this.createNewClusterButton = this.createNewClusterButton = page
            .getByRole('button', {
            name: 'Create new cluster',
        })
            .or(this.page.getByRole('button', {
            name: 'Create cluster',
        }));
        this.clusterNameInput = page.getByPlaceholder('Enter a name for the cluster');
        this.createClusterButton = page.getByRole('button', {
            name: 'Create cluster',
        });
        this.clusterCreatingStatusText = page.getByText('Creating', { exact: true });
        this.clusterHealthyStatusText = page.getByText('Healthy', { exact: true });
        this.clusterHealthyIndicatorSelector = '[class="healthy healthIndicator"]';
        this.clusterGenerationCompleteMessage = page.getByText('Test Cluster is healthy and ready to use');
        this.clustersBreadcrumb = page
            .getByLabel('Breadcrumb')
            .getByText('Clusters', { exact: true });
        this.deleteClusterButton = page.getByRole('button', { name: 'Delete' });
        this.confirmDeleteInput = page.getByRole('textbox', {
            name: 'Type the word DELETE to confirm',
        });
        this.dangerDeleteButton = page.getByRole('button', { name: 'danger Delete' });
        this.connectorSecretsTab = page.getByRole('tab', {
            name: 'Connector Secrets',
        });
        this.createAClusterButton = page.getByRole('button', {
            name: 'Create a Cluster',
        });
        this.clusterVersionOption = page
            .locator('label')
            .filter({ hasText: `${process.env.CLUSTER_VERSION}` })
            .locator('span')
            .first();
        this.alphaTab = page.getByRole('tab', { name: 'Alpha' });
        this.devTab = page.getByRole('tab', { name: 'Internal Dev' });
        this.stableTab = page.getByRole('tab', { name: 'Stable' });
        this.qaGenerationsTab = page.getByRole('tab', { name: 'QA Generations' });
        this.gcpRegion = page.getByRole('tab', {
            name: 'GCP',
        });
        this.londonRegion = page.locator('label').filter({
            hasText: 'London, Europe (europe-west2)',
        });
        this.g3DevClusterType = page.locator('label').filter({
            hasText: this.defaultClusterType,
        });
        this.belgiumRegion = page.locator('label').filter({
            hasText: 'Chaos, Belgium, Europe (europe-west1)',
        });
        this.finlandRegion = page.locator('label').filter({
            hasText: 'Finland, Europe (europe-north1)',
        });
        this.clustersList = page
            .getByRole('row')
            .filter({ hasNotText: 'Generation' }); //Filter out header row
        this.cluster = (clusterName) => this.clustersList.filter({ hasText: clusterName });
        this.clusterHealthiness = (clusterName) => this.cluster(clusterName).getByText(`Healthy`, {
            exact: true,
        });
        this.clusterLink = (clusterName) => this.cluster(clusterName).getByRole('link', {
            name: clusterName,
        });
        this.clusterDeleteButton = (clusterName) => this.cluster(clusterName).getByRole('button', { name: 'Delete' });
    }
    async clickClusterBanner() {
        await this.page
            .getByRole('banner')
            .getByRole('link', { name: 'Clusters' })
            .click({ timeout: 60000 });
    }
    async deleteCluster(name) {
        const clusterInstance = this.cluster(name).first();
        if ((await clusterInstance.count()) <= 0) {
            console.log(`No clusters found with name ${name}, skipping deletion.`);
            return;
        }
        while ((await this.clusterDeleteButton(name).count()) > 0) {
            const deleteButton = this.clusterDeleteButton(name).nth(0);
            if (await deleteButton.isVisible()) {
                try {
                    await deleteButton.click({ force: true, timeout: 60000 });
                }
                catch (error) {
                    await this.clickClusterBanner();
                    await (0, test_1.expect)(deleteButton).toBeVisible({ timeout: 60000 });
                    await deleteButton.click({ force: true, timeout: 60000 });
                }
                await this.confirmDeleteInput.click({ force: true, timeout: 60000 });
                await this.confirmDeleteInput.fill('DELETE', { timeout: 60000 });
                const dangerDeleteButtons = await this.dangerDeleteButton.all();
                const lastDangerDeleteButton = dangerDeleteButtons[dangerDeleteButtons.length - 1];
                await lastDangerDeleteButton.click();
                await (0, test_1.expect)(this.page.getByText('Deleting...')).not.toBeVisible({
                    timeout: 60000,
                });
            }
        }
    }
    async createClusterIfNotExists(clusterName, region = 'GCP') {
        await (0, sleep_1.sleep)(10000);
        if ((await this.cluster(clusterName).isVisible({ timeout: 20000 })) &&
            (await this.clusterHealthiness(clusterName).isVisible({ timeout: 20000 }))) {
            console.log(`${clusterName} exists and is healthy.`);
        }
        else {
            await this.createCluster(clusterName, region);
            await this.assertClusterHealthyStatusWithRetry(clusterName, 300000);
        }
    }
    async assertClusterHealthyStatusWithRetry(name, visibilityTimeout = 100000, totalTimeout = 420000) {
        await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.clusterHealthiness(name), {
            visibilityTimeout: visibilityTimeout,
            totalTimeout: totalTimeout,
            maxRetries: 5,
            preAction: async () => {
                await this.page.reload();
                await (0, test_1.expect)(this.cluster(name)).toBeVisible({ timeout: 10000 });
            },
        });
        console.log('Cluster is healthy:', name);
    }
    async clickCreateNewClusterButton() {
        await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.createNewClusterButton, {
            visibilityTimeout: 20000,
            totalTimeout: 80000,
            postAction: async () => {
                await this.clickClusterBanner();
            },
        });
    }
    async clickClusterNameInput() {
        await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.clusterNameInput, {
            postAction: async () => {
                await this.clickClusterBanner();
            },
        });
    }
    async fillClusterNameInput(name) {
        await this.clusterNameInput.fill(name);
    }
    async clickCreateClusterButton() {
        await this.createClusterButton.click();
    }
    async clickClustersBreadcrumb(clusterName) {
        const creatingCheckRegex = new RegExp(`${clusterName}.*?Creatingdev`);
        const healthyCheckRegex = new RegExp(`${clusterName}.*?Healthydev`);
        try {
            await (0, test_1.expect)(this.clustersBreadcrumb).toBeVisible({ timeout: 60000 });
            await this.clustersBreadcrumb.click({ timeout: 60000 });
            await (0, test_1.expect)(this.page.getByText(creatingCheckRegex)).toBeVisible({
                timeout: 30000,
            });
        }
        catch (error) {
            await this.clickClusterBanner();
            await (0, test_1.expect)(this.page
                .getByText(creatingCheckRegex)
                .first()
                .or(this.page.getByText(healthyCheckRegex))).toBeVisible({
                timeout: 30000,
            });
        }
    }
    async clickConnectorSecretesTab(clusterName) {
        await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.connectorSecretsTab, {
            postAction: async () => {
                await this.clickClusterBanner();
                await this.clickClusterLink(clusterName);
            },
        });
    }
    async clickClusterLink(name) {
        await (0, clickLocatorWithRetry_1.clickLocatorWithRetry)(this.page, this.clusterLink(name), {
            postAction: async () => {
                await this.clickClusterBanner();
            },
        });
    }
    async clickClusterTab() {
        await Promise.race([
            this.page.waitForURL(/\/clusters/, {
                timeout: 60000,
            }),
            this.clickClusterBanner(),
        ]);
    }
    async createCluster(name, region = 'GCP') {
        await this.clickClusterTab();
        await this.deleteCluster(name);
        await this.clickCreateNewClusterButton();
        await this.clickClusterNameInput();
        await this.fillClusterNameInput(name);
        await this.clickClusterType();
        await this.clickCloudProvider(region);
        await this.selectSubRegion(region);
        await this.clickClusterOption();
        await this.clickCreateClusterButton();
        await this.logClusterCreationInfo(name);
        await this.clickClustersBreadcrumb(name);
    }
    async selectSubRegion(region) {
        if (region === 'GCP') {
            if (process.env.IS_PROD == 'true') {
                await (0, test_1.expect)(this.londonRegion).toBeVisible({ timeout: 15000 });
                await this.londonRegion.click();
            }
            else {
                const regions = [
                    { name: 'Belgium', locator: this.belgiumRegion },
                    { name: 'Finland', locator: this.finlandRegion },
                ];
                const chosen = regions[Math.floor(Math.random() * regions.length)];
                console.log(`Selected region: ${chosen.name}`);
                await (0, test_1.expect)(chosen.locator).toBeVisible({ timeout: 20000 });
                await chosen.locator.click();
            }
        }
    }
    async logClusterCreationInfo(clusterName) {
        try {
            await this.page.waitForURL(/\/cluster\/[a-f0-9-]+$/, { timeout: 60000 });
            const currentUrl = this.page.url();
            const clusterId = this.extractClusterIdFromUrl(currentUrl);
            console.log(`🎉 Cluster "${clusterName}" created successfully with ID: ${clusterId || 'Unknown'} at ${new Date().toISOString()}`);
        }
        catch (error) {
            console.warn(`⚠️ Could not extract cluster info for "${clusterName}": ${error}`);
        }
    }
    extractClusterIdFromUrl(url) {
        const clusterIdMatch = url.match(/\/cluster\/([a-f0-9-]+)/);
        return clusterIdMatch ? clusterIdMatch[1] : null;
    }
    async clickCloudProvider(region = 'GCP') {
        const provider = this.page.getByRole('tab', { name: region });
        await (0, test_1.expect)(provider).toBeVisible({ timeout: 60000 });
        await provider.click();
    }
    async clickClusterType() {
        if (process.env.IS_PROD !== 'true') {
            await (0, test_1.expect)(this.g3DevClusterType).toBeVisible({ timeout: 60000 });
            await this.g3DevClusterType.click();
        }
    }
    async clickClusterOption() {
        const tabs = [
            this.clickStableTab,
            this.clickDevTab,
            this.clickQAGenerationsTab,
            this.clickAlphaTab,
        ];
        for (const clickTab of tabs) {
            try {
                await clickTab.call(this);
                await this.clusterVersionOption.click({ timeout: 25000 });
                return;
            }
            catch (error) {
                console.error('Error clicking tab or cluster version option:', error);
            }
        }
        throw new Error('Failed to find cluster generation');
    }
    async clickAlphaTab() {
        await this.alphaTab.click();
    }
    async clickDevTab() {
        await this.devTab.click();
    }
    async clickStableTab() {
        await this.stableTab.click();
    }
    async clickQAGenerationsTab() {
        await this.qaGenerationsTab.click();
    }
}
exports.ClusterPage = ClusterPage;
