package com.sonymusic

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

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

class SuiteAppDeployPrInstanceTest extends BaseGlobalVarTest {
    def final CHANGE_ID = '1234'
    def suiteAppDeployPrInstance

    @BeforeEach
    void setUp() {
        super.setUp()
        suiteAppDeployPrInstance = loadScript('vars/suiteAppDeployPrInstance.groovy')
        helper.registerAllowedMethod('suiteAppBuild', [Map])
        helper.registerAllowedMethod('suiteAppPublish', [Map])
        helper.registerAllowedMethod('githubPostPrComment', [Map])
        binding.setVariable('env', ['CHANGE_ID': CHANGE_ID])
    }

    void assertSuiteAppPublish(String appName, String pullRequestId){
        assertMethodCalledOnceWith('suiteAppPublish', [
            'env=qa',
            "appName=${appName}",
            "subpath=prs/${pullRequestId}"
        ])
    }

    void assertGithubPostPrComment(String appName, String pullRequestId){
        assertMethodCalledOnceWith('githubPostPrComment', [
            "repo=${appName}",
            "message=🚀 PR-Instance successfully deployed to: https://${appName}-${pullRequestId}.pullrequests.qaorch.com"
        ])
    }

    @Test
    void testCallWithInvalidArgs() {
        assertThrowsWithMessage(
            IllegalArgumentException.class,
            "suiteAppDeployPrInstance: Missing required parameter: 'appName'",
            { suiteAppDeployPrInstance.call() }
        )
    }

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

        assertThrowsWithMessage(
            AssertionError.class,
            'suiteAppDeployPrInstance: Failed to determine the PR id, please make sure you are running in a PR branch',
            { suiteAppDeployPrInstance.call(appName: 'frontend-test') }
        )
    }

    @Test
    void testCallWithAppName() {
        def appName = 'test-app'

        assertNull(suiteAppDeployPrInstance(
            appName: appName
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend build --public-path https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/]",
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/",
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com"
        ])

        assertSuiteAppPublish(appName, CHANGE_ID)
        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithEnvVars() {
        def appName = 'frontend-test'

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            envVars: [GRAPHQL_URL: 'test', OTHER: 'custom']
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend build --public-path https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/]",
            'GRAPHQL_URL=test',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/",
            'OTHER=custom',
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com"
        ])

        assertSuiteAppPublish(appName, CHANGE_ID)
        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithPullRequestId() {
        def appName = 'frontend-test'
        def pullRequestId = '999'

        binding.setVariable('env', [:])

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            pullRequestId: pullRequestId
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend build --public-path https://qa-cdn.theorchard.io/${appName}/prs/${pullRequestId}/]",
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${pullRequestId}/",
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${pullRequestId}.pullrequests.qaorch.com"
        ])

        assertSuiteAppPublish(appName, pullRequestId)
        assertGithubPostPrComment(appName, pullRequestId)
    }

    @Test
    void testCallWithPoEditorEnvVars() {
        def appName = 'frontend-test'

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            envVars: [POEDITOR_PROJECT_ID: '123']
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend i18n:download, frontend build --public-path https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/]",
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/",
            'POEDITOR_PROJECT_ID=123',
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com"
        ])

        assertSuiteAppPublish(appName, CHANGE_ID)
        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithDetectPackageManagerFalse() {
        def appName = 'test-app'

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            detectPackageManager: false
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend build --public-path https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/]",
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/",
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com",
            'detectPackageManager=false'
        ])

        assertSuiteAppPublish(appName, CHANGE_ID)
        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithDetectPackageManagerTrue() {
        def appName = 'test-app'

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            detectPackageManager: true
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend build --public-path https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/]",
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/",
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com",
            'detectPackageManager=true'
        ])

        assertSuiteAppPublish(appName, CHANGE_ID)
        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithScriptNames() {
        def appName = 'test-app'

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            scriptNames: ['build:pri']
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            'scriptNames=[build:pri]',
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/",
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com"
        ])

        assertSuiteAppPublish(appName, CHANGE_ID)
        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithScriptNamesIgnoresPoEditor() {
        def appName = 'test-app'

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            scriptNames: ['build:pri'],
            envVars: [POEDITOR_PROJECT_ID: '123']
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            'scriptNames=[build:pri]',
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            'CDN_URL=https://qa-cdn.theorchard.io',
            "PUBLIC_PATH=https://qa-cdn.theorchard.io/${appName}/prs/${CHANGE_ID}/",
            'POEDITOR_PROJECT_ID=123',
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com"
        ])

        assertSuiteAppPublish(appName, CHANGE_ID)
        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithBucket() {
        def appName = 'test-app'
        def bucket = 'my-s3-bucket.domain.com'
        def expectedCdnUrl = "https://${bucket}"

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            bucket: bucket
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend build --public-path ${expectedCdnUrl}/${appName}/prs/${CHANGE_ID}/]",
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            "CDN_URL=${expectedCdnUrl}",
            "PUBLIC_PATH=${expectedCdnUrl}/${appName}/prs/${CHANGE_ID}/",
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com"
        ])

        assertMethodCalledOnceWith('suiteAppPublish', [
            'env=qa',
            "appName=${appName}",
            "subpath=prs/${CHANGE_ID}",
            "bucket=${bucket}"
        ])

        assertGithubPostPrComment(appName, CHANGE_ID)
    }

    @Test
    void testCallWithBucketOverridesCdnUrl() {
        def appName = 'test-app'
        def bucket = 'my-s3-bucket.domain.com'
        def expectedCdnUrl = "https://${bucket}"

        assertNull(suiteAppDeployPrInstance(
            appName: appName,
            bucket: bucket,
            cdnUrl: 'https://some-other-cdn.example.com'
        ))

        assertMethodCalledOnceWith('suiteAppBuild', [
            'env=qa',
            "scriptNames=[frontend build --public-path ${expectedCdnUrl}/${appName}/prs/${CHANGE_ID}/]",
            'GRAPHQL_URL=https://grassproxy.pullrequests.qaorch.com/graphql-router/graphql',
            "CDN_URL=${expectedCdnUrl}",
            "PUBLIC_PATH=${expectedCdnUrl}/${appName}/prs/${CHANGE_ID}/",
            "AUTH0_REDIRECT_URI=https://pullrequests.qaorch.com/auth0Redirect?to=${appName}-${CHANGE_ID}.pullrequests.qaorch.com"
        ])

        assertMethodCalledOnceWith('suiteAppPublish', [
            'env=qa',
            "appName=${appName}",
            "subpath=prs/${CHANGE_ID}",
            "bucket=${bucket}"
        ])

        assertGithubPostPrComment(appName, CHANGE_ID)
    }
}
