String GITHUB_REPOSITORY = 'qa-automation-tools'
def isGithubRetestComment = env.GITHUB_COMMENT && env.GITHUB_COMMENT.toLowerCase().contains('jenkins retest')

pipeline {
    agent any

    options {
        ansiColor('xterm')
        disableConcurrentBuilds()
        timestamps()
        buildDiscarder(logRotator(numToKeepStr: '30'))
        timeout(time: 30, unit: 'MINUTES')
    }

    parameters {
        string(
            name: 'SHARED_LIBRARIES_VERSION',
            defaultValue: 'master',
            description: 'The version of the Jenkins shared libraries to use. Can be a branch, tag or Git revision.'
        )
        booleanParam(
            name: 'RUN_CREATE_USER',
            defaultValue: false,
            description: 'True to run create-test-user, false to run CI checks only.'
        )
        booleanParam(
            name: 'RUN_RESET_OA_USERS',
            defaultValue: false,
            description: 'True to reset OA Cypress test user passwords in Auth0 and AWS Secrets Manager.'
        )
        string(
            name: 'RESET_USERS',
            defaultValue: '',
            description: 'Comma-separated user keys to reset (e.g., cypress_manager,cypress_manager_1). Leave blank to reset all 5 cypress_manager users.'
        )
        choice(
            name: 'APP',
            choices: ['workstation', 'insights', 'fansifter', 'content', 'distribution', 'moneyhub', 'collaborators', 'abacus', 'publishing', 'settings', 'documents', 'oa'],
            description: 'Application under test (only used when RUN_CREATE_USER is true).'
        )
        string(
            name: 'VENDOR_ID',
            defaultValue: '',
            description: 'Vendor ID (e.g., 18805). Required when RUN_CREATE_USER is true.'
        )
        string(
            name: 'VENDOR_NAME',
            defaultValue: '',
            description: 'Vendor Name (e.g., Allegro). Required when RUN_CREATE_USER is true.'
        )
        string(
            name: 'ADDITIONAL_DETAIL',
            defaultValue: '',
            description: 'Additional detail for email (e.g., label_18805). Defaults to label_<VENDOR_ID> if empty.'
        )
        string(
            name: 'FIRST_NAME',
            defaultValue: 'Test',
            description: 'First name for the test user.'
        )
        string(
            name: 'LAST_NAME',
            defaultValue: 'Tester',
            description: 'Last name for the test user.'
        )
        booleanParam(
            name: 'IS_SUBACCOUNT',
            defaultValue: false,
            description: 'Flag this as a subaccount user.'
        )
        string(
            name: 'SUBACCOUNT_ID',
            defaultValue: '',
            description: 'Subaccount ID (only when IS_SUBACCOUNT is true).'
        )
        booleanParam(
            name: 'IS_ADMIN',
            defaultValue: false,
            description: 'Grant admin access (auto-selects admin roles).'
        )
        string(
            name: 'ROLES',
            defaultValue: 'catalog',
            description: 'Comma-separated roles (e.g., catalog,analytics). Ignored when IS_ADMIN is true.'
        )
        string(
            name: 'SECRET_KEY',
            defaultValue: '',
            description: 'AWS Secret key for storing user data. Defaults to label_<VENDOR_ID> if empty.'
        )
        string(
            name: 'START_FROM',
            defaultValue: '',
            description: 'Start from a specific step number (1-11). Useful for resuming a failed run.'
        )
    }

    triggers {
        issueCommentTrigger('.*jenkins retest.*')
    }

    stages {
        stage('Set Build Name') {
            steps {
                script {
                    def branchLabel = env.BRANCH_NAME ?: 'unknown'
                    if (params.RUN_CREATE_USER) {
                        currentBuild.displayName = "#${BUILD_NUMBER} - Create User: ${params.APP} / ${params.VENDOR_NAME}"
                    } else if (params.RUN_RESET_OA_USERS) {
                        currentBuild.displayName = "#${BUILD_NUMBER} - Reset OA Users"
                    } else {
                        currentBuild.displayName = "#${BUILD_NUMBER} - ${branchLabel}"
                    }
                    currentBuild.description = "Commit: ${env.GIT_COMMIT?.take(8) ?: 'N/A'}"
                }
            }
        }

        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }

        stage('Checkout') {
            steps {
                cleanWs()
                checkout scm
                echo "Branch: ${env.BRANCH_NAME}"
                echo "Commit: ${env.GIT_COMMIT}"
            }
        }

        stage('Quality Checks') {
            when {
                expression { !params.RUN_CREATE_USER && !params.RUN_RESET_OA_USERS }
            }
            parallel {
                stage('Lint') {
                    steps {
                        echo '=== Running ESLint ==='
                        pnpmRun(scriptNames: ['lint'])
                    }
                }
                stage('Format') {
                    steps {
                        echo '=== Running Prettier ==='
                        pnpmRun(scriptNames: ['format'])
                    }
                }
            }
        }

        stage('Unit Tests') {
            when {
                expression { !params.RUN_CREATE_USER && !params.RUN_RESET_OA_USERS }
            }
            steps {
                echo '=== Running Vitest ==='
                pnpmRun(scriptNames: ['test'])
            }
        }

        stage('Validate Parameters') {
            when {
                expression { params.RUN_CREATE_USER }
            }
            steps {
                script {
                    if (!params.VENDOR_ID?.trim()) {
                        error 'VENDOR_ID is required when RUN_CREATE_USER is true.'
                    }
                    if (!params.VENDOR_NAME?.trim()) {
                        error 'VENDOR_NAME is required when RUN_CREATE_USER is true.'
                    }
                    echo "=== Parameters validated ==="
                    echo "App: ${params.APP}"
                    echo "Vendor: ${params.VENDOR_ID} (${params.VENDOR_NAME})"
                    echo "Admin: ${params.IS_ADMIN}"
                    echo "Roles: ${params.ROLES}"
                }
            }
        }

        // TODO: Both 'Create Test User' and 'Reset OA Users' stages currently run on-prem.
        // These should be moved to use the nodeSh/Docker approach (like pnpmRun) so they
        // run in the standard node22 container with a clean, reproducible environment.
        stage('Create Test User') {
            when {
                expression { params.RUN_CREATE_USER }
            }
            steps {
                script {
                    echo '=== Running create-test-user ==='

                    def args = [
                        "--yes",
                        "--app ${params.APP}",
                        "--vendor-id ${params.VENDOR_ID}",
                        "--vendor-name '${params.VENDOR_NAME}'",
                        "--first-name '${params.FIRST_NAME}'",
                        "--last-name '${params.LAST_NAME}'"
                    ]

                    if (!params.IS_ADMIN && params.ROLES?.trim()) {
                        args.add("--roles '${params.ROLES}'")
                    }

                    if (params.ADDITIONAL_DETAIL?.trim()) {
                        args.add("--additional-detail '${params.ADDITIONAL_DETAIL}'")
                    }
                    if (params.SECRET_KEY?.trim()) {
                        args.add("--secret-key '${params.SECRET_KEY}'")
                    }
                    if (params.IS_SUBACCOUNT) {
                        args.add("--is-subaccount")
                        if (params.SUBACCOUNT_ID?.trim()) {
                            args.add("--subaccount-id ${params.SUBACCOUNT_ID}")
                        }
                    }
                    if (params.IS_ADMIN) {
                        args.add("--is-admin")
                    }
                    if (params.START_FROM?.trim()) {
                        args.add("--start-from ${params.START_FROM}")
                    }

                    def cmd = "pnpm create-test-user -- ${args.join(' ')}"
                    echo "Command: ${cmd}"
                    sh cmd
                }
            }
        }

        stage('Reset OA Users') {
            when {
                expression { params.RUN_RESET_OA_USERS }
            }
            steps {
                script {
                    echo '=== Running reset-oa-users ==='

                    def args = ["--yes"]

                    if (params.RESET_USERS?.trim()) {
                        args.add("--users '${params.RESET_USERS}'")
                    }

                    def cmd = "pnpm reset-oa-users ${args.join(' ')}"
                    echo "Command: ${cmd}"
                    sh """
                        corepack enable pnpm
                        pnpm install --frozen-lockfile
                        ${cmd}
                    """
                }
            }
        }

        stage('Validate Software Catalog Definition') {
            when {
                allOf {
                    branch 'master'
                    expression { !params.RUN_CREATE_USER && !params.RUN_RESET_OA_USERS }
                }
            }
            steps {
                datadogSoftwareCatalogPublish()
            }
        }
    }

    post {
        always {
            echo "Pipeline result: ${currentBuild.currentResult}"
        }
        failure {
            script {
                slackSend(
                    color: 'danger',
                    channel: '#playwright-test-e2e-results',
                    message: ":x: *${GITHUB_REPOSITORY}* — <${env.BUILD_URL}|#${env.BUILD_NUMBER}> on `${env.BRANCH_NAME}` *FAILED*"
                )
            }
        }
        fixed {
            script {
                slackSend(
                    color: 'good',
                    channel: '#playwright-test-e2e-results',
                    message: ":white_check_mark: *${GITHUB_REPOSITORY}* — <${env.BUILD_URL}|#${env.BUILD_NUMBER}> on `${env.BRANCH_NAME}` *FIXED*"
                )
            }
        }
    }
}
