package com.sonymusic

import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

import static org.junit.jupiter.api.Assertions.assertEquals

class GithubPostCommitStatusTest extends BaseGlobalVarTest {
    def githubPostCommitStatus
    def response = [id: '123']

    @BeforeEach
    void setUp() {
        super.setUp()
        githubPostCommitStatus = loadScript('vars/githubPostCommitStatus.groovy')
        binding.setVariable('env', ['GIT_COMMIT': '83221630d34b66cac6fe4ef919d13be8bda5e3b3', 'JOB_URL': 'http://localhost/test-job'])
        helper.registerAllowedMethod('withCredentials', [Map])
        helper.registerAllowedMethod('sh', [Map])
        helper.registerAllowedMethod('readJSON', [Map], {
            return response
        })
    }

    @Test
    void testCallWithNoArgs() {
        assertThrowsWithMessage(
            IllegalArgumentException.class,
            "githubPostCommitStatus: Missing required parameter: 'repo'",
            { githubPostCommitStatus.call(state: 'SUCCESS', description: 'Test message', context: 'test-job') }
        )
        assertThrowsWithMessage(
            IllegalArgumentException.class,
            "githubPostCommitStatus: Missing required parameter: 'state'",
            { githubPostCommitStatus.call(repo: 'frontend-test', description: 'Test message', context: 'test-job') }
        )
        assertThrowsWithMessage(
            IllegalArgumentException.class,
            "githubPostCommitStatus: Missing required parameter: 'description'",
            { githubPostCommitStatus.call(repo: 'frontend-test', state: 'SUCCESS', context: 'test-job') }
        )
        assertThrowsWithMessage(
            IllegalArgumentException.class,
            "githubPostCommitStatus: Missing required parameter: 'context'",
            { githubPostCommitStatus.call(repo: 'frontend-test', state: 'SUCCESS', description: 'Test message') }
        )
    }

    @Test
    void testCallWithNoEnvVars() {
        binding.setVariable('env', [:])

        assertThrowsWithMessage(
            AssertionError.class,
            "githubPostCommitStatus: commitHash is required if env.GIT_COMMIT is not available.",
            { githubPostCommitStatus.call(repo: 'frontend-test', state: 'SUCCESS', description: 'Test message', context: 'test-job') }
        )

        binding.setVariable('env', ['GIT_COMMIT': '83221630d34b66cac6fe4ef919d13be8bda5e3b3'])
        assertThrowsWithMessage(
            AssertionError.class,
            "githubPostCommitStatus: targetUrl is required if env.JOB_URL is not available.",
            { githubPostCommitStatus.call(repo: 'frontend-test', state: 'SUCCESS', description: 'Test message', context: 'test-job') }
        )
    }

    @Test
    void testCallSuccess() {
        def comment = githubPostCommitStatus(
            repo: 'frontend-test',
            state: 'SUCCESS',
            description: 'Test message',
            context: 'test-job',
        )

        assertMethodCalledOnceWith('withCredentials', '[GITHUB_TOKEN]')
        assertMethodCalledOnceWith('sh', [
            'curl -X POST',
            '-H "Authorization: token \${GITHUB_TOKEN}"',
            '"state":"SUCCESS","target_url":"http://localhost/test-job","description":"Test message","context":"test-job"',
            'https://api.github.com/repos/theorchard/frontend-test/statuses/83221630d34b66cac6fe4ef919d13be8bda5e3b3'
        ])

        assertEquals(comment, response)
    }

    @Test
    void testCallWithOwner() {
        githubPostCommitStatus(
            repo: 'frontend-test',
            state: 'SUCCESS',
            description: 'Test message',
            context: 'test-job',
            owner: 'sme',
        )

        assertMethodCalledTimes('withCredentials', 1)
        assertMethodCalledOnceWith('sh', [
            '"state":"SUCCESS","target_url":"http://localhost/test-job","description":"Test message","context":"test-job"',
            'https://api.github.com/repos/sme/frontend-test/statuses/83221630d34b66cac6fe4ef919d13be8bda5e3b3'
        ])
    }

    @Test
    void testCallWithCommitHash() {
        githubPostCommitStatus(
            repo: 'frontend-test',
            state: 'SUCCESS',
            description: 'Test message',
            context: 'test-job',
            commitHash: 'e8b045033bbe47366dab676a030d9ba8bebd128d',
        )

        assertMethodCalledTimes('withCredentials', 1)
        assertMethodCalledOnceWith('sh', [
            '"state":"SUCCESS","target_url":"http://localhost/test-job","description":"Test message","context":"test-job"',
            'https://api.github.com/repos/theorchard/frontend-test/statuses/e8b045033bbe47366dab676a030d9ba8bebd128d'
        ])
    }

    @Test
    void testCallWithTargetUrl() {
        githubPostCommitStatus(
            repo: 'frontend-test',
            state: 'SUCCESS',
            description: 'Test message',
            context: 'test-job',
            targetUrl: 'http://example.com/some-other-job',
        )

        assertMethodCalledTimes('withCredentials', 1)
        assertMethodCalledOnceWith('sh', [
            '"state":"SUCCESS","target_url":"http://example.com/some-other-job","description":"Test message","context":"test-job"',
            'https://api.github.com/repos/theorchard/frontend-test/statuses/83221630d34b66cac6fe4ef919d13be8bda5e3b3'
        ])
    }
}
