package com.sonymusic

import hudson.model.Result
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

import static org.codehaus.groovy.runtime.IOGroovyMethods.withCloseable
import static org.mockito.ArgumentMatchers.anyString
import static org.mockito.Mockito.mockStatic

class CheckMainPipelineStatusTest extends BaseGlobalVarTest {
    def checkMainPipelineStatus

    @BeforeEach
    void setUp() {
        super.setUp()
        checkMainPipelineStatus = loadScript('vars/checkMainPipelineStatus.groovy')
        binding.setVariable('env', ['JOB_NAME': 'org/project/PR-811/test-job', 'JENKINS_URL': 'http://localhost/' ])
        helper.registerAllowedMethod('githubPostCommitStatus', [Map])
    }

    @Test
    void testCallWithNoEnvVars() {
        binding.setVariable('env', [:])
        assertThrowsWithMessage(
            AssertionError.class,
            "checkMainPipelineStatus: jobName is required if env.JOB_NAME is not available.",
            { checkMainPipelineStatus.call() }
        )
    }

    @Test
    void testCallNotPR() {
        binding.setVariable('env', ['JOB_NAME': 'org/project/master/test-job', 'JENKINS_URL': 'http://localhost/' ])
        checkMainPipelineStatus()
        assertMethodCalledOnceWith('echo', 'Not a pull request, skipping the step.')
    }

    @Test
    void testCallMainSuccess() {
        withCloseable(mockStatic(MetadataUtils.class) as Closeable) { mockedMetadataUtils ->
            // Define the behavior of the static method
            mockedMetadataUtils.when({ MetadataUtils.getLastCompletedBuildStatus(anyString()) })
                .thenReturn(Result.SUCCESS)
            checkMainPipelineStatus.call()
            assertMethodCalledOnceWith('githubPostCommitStatus', [
                'project',
                'success',
                'The build pipeline for this service is green.',
                'Main Branch Pipeline Status',
                'http://localhost/job/org/job/project/job/master/',
            ])
        }
    }

    @Test
    void testCallMainFailure() {
        withCloseable(mockStatic(MetadataUtils.class) as Closeable) { mockedMetadataUtils ->
            // Define the behavior of the static method
            mockedMetadataUtils.when({ MetadataUtils.getLastCompletedBuildStatus(anyString()) })
                .thenReturn(Result.FAILURE)
            checkMainPipelineStatus.call()
            assertMethodCalledOnceWith('githubPostCommitStatus', [
                'project',
                'failure',
                "CAUTION: The build pipeline for this service is red. Last build status: FAILURE.",
                'Main Branch Pipeline Status',
                'http://localhost/job/org/job/project/job/master/',
            ])
        }
    }

    @Test
    void testCallNullBuildResults() {
        withCloseable(mockStatic(MetadataUtils.class) as Closeable) { mockedMetadataUtils ->
            // Define the behavior of the static method
            mockedMetadataUtils.when({ MetadataUtils.getLastCompletedBuildStatus(anyString()) })
                .thenReturn(null)
            checkMainPipelineStatus.call()
            assertMethodCalledNthWith(
                'echo',
                1,
                'Unable to get status of last successful build ' +
                'for org/project/master, skipping the step.')
        }
    }
}
