package com.sonymusic

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

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

class PackageManagerRunTest extends BaseGlobalVarTest {
    def packageManagerRun

    @BeforeEach
    void setUp() {
        super.setUp()
        packageManagerRun = loadScript('vars/packageManagerRun.groovy')

        helper.registerAllowedMethod('readFile', [String], { String path ->
            return binding.getVariable('packageJsonContent')
        })
        helper.registerAllowedMethod('npmRun', [Map])
        helper.registerAllowedMethod('pnpmRun', [Map])
        helper.registerAllowedMethod('yarnRun', [Map])
        binding.setVariable('env', [:])
    }

    @Test
    void testCallWithNoArgs() {
        assertThrowsWithMessage(
            IllegalArgumentException.class,
            "packageManagerRun: Missing required parameter: 'scriptNames'",
            { packageManagerRun.call() }
        )
    }

    @Test
    void testCallWithNpm() {
        binding.setVariable('packageJsonContent', '{"name": "test", "packageManager": "npm@10.0.0"}')

        assertNull(
            packageManagerRun(scriptNames: ['test'])
        )

        assertMethodCalledOnceWith('npmRun', [
            'scriptNames=[test]'
        ])
    }

    @Test
    void testCallWithNpmWithoutVersion() {
        binding.setVariable('packageJsonContent', '{"name": "test", "packageManager": "npm"}')

        assertNull(
            packageManagerRun(scriptNames: ['test'])
        )

        assertMethodCalledOnceWith('npmRun', [
            'scriptNames=[test]'
        ])
    }

    @Test
    void testCallWithPnpm() {
        binding.setVariable('packageJsonContent', '{"name": "test", "packageManager": "pnpm@8.0.0"}')

        assertNull(
            packageManagerRun(scriptNames: ['lint', 'test'])
        )

        assertMethodCalledOnceWith('pnpmRun', [
            'scriptNames=[lint, test]'
        ])
    }

    @Test
    void testCallWithYarn() {
        binding.setVariable('packageJsonContent', '{"name": "test", "packageManager": "yarn@3.0.0"}')

        assertNull(
            packageManagerRun(scriptNames: ['build'])
        )

        assertMethodCalledOnceWith('yarnRun', [
            'scriptNames=[build]'
        ])
    }

    @Test
    void testCallWithNoPackageManager() {
        binding.setVariable('packageJsonContent', '{"name": "test"}')

        assertNull(
            packageManagerRun(scriptNames: ['test'])
        )

        assertMethodCalledOnceWith('yarnRun', [
            'scriptNames=[test]'
        ])
    }

    @Test
    void testCallWithUnsupportedPackageManager() {
        binding.setVariable('packageJsonContent', '{"name": "test", "packageManager": "bun@1.0.0"}')

        assertNull(
            packageManagerRun(scriptNames: ['test'])
        )

        assertMethodCalledOnceWith('yarnRun', [
            'scriptNames=[test]'
        ])
    }

    @Test
    void testCallWithNodeVersion() {
        binding.setVariable('packageJsonContent', '{"name": "test", "packageManager": "npm@10.0.0"}')

        assertNull(
            packageManagerRun(scriptNames: ['test'], nodeVersion: '22.1.1')
        )

        assertMethodCalledOnceWith('npmRun', [
            'nodeVersion=22.1.1'
        ])
    }

    @Test
    void testCallWithEnvVars() {
        binding.setVariable('packageJsonContent', '{"name": "test", "packageManager": "pnpm@8.0.0"}')

        assertNull(
            packageManagerRun(
                scriptNames: ['test'],
                envVars: [TEST: 'value']
            )
        )

        assertMethodCalledOnceWith('pnpmRun', [
            'envVars={TEST=value}'
        ])
    }
}
