import groovy.transform.Field
import com.sonymusic.*

def call(Map args = [:]) {
    nodeSh(args)
}

def call(String script) {
    nodeSh(script: script)
}

// auth0 supports only node18 for now, so we need to support it
@Field SUPPORTED_NODE_VERSIONS = ['18', '20.11.1', '20', '20-build', '22', '24']
@Field NODE_VERSION_MAP = [
    'lts/hydrogen': '18',
    '20.x': '20'
]

def nodeSh(Map args) {
    def params = Utils.validateParams('nodeSh', args, [
        script: [type: String, required: true],
        nodeVersion: [type: String, required: false],
        envVars: [type: Map, required: false, defaultValue: [:]],
        user: [type: String, required: false, defaultValue: 'node']
    ])

    def nodeVersion = params.nodeVersion ?: getNodeVersionFromNvmrc()
    assert nodeVersion: 'nodeSh: The "nodeVersion" parameter is required when there is no .nvmrc file in the repo.'

    if(NODE_VERSION_MAP.containsKey(nodeVersion)) {
        nodeVersion = NODE_VERSION_MAP[nodeVersion]
    }

    if(!SUPPORTED_NODE_VERSIONS.contains(nodeVersion)) {
        throw new IllegalArgumentException("nodeSh: The node version '${nodeVersion}' is not supported. Supported versions: [${SUPPORTED_NODE_VERSIONS.join(',')}]")
    }

    def envVars = [GITHUB_NPM_TOKEN: "\${GITHUB_NPM_TOKEN}"]

    // Since we are mounting the workspace directory to the working directory in the container,
    // we need to change the file permissions for the repo so the docker container can access it.
    // But if the "node_modules" folder exists, we can safely assume we have alreay done this.
    // And changing the permissions for the "node_modules" folder would fail and would be slow.
    if(!fileExists('./node_modules')) {
        // Use -f flag to ignore errors when there are files in the workspace which are
        // owned by the container user (e.g. created from a previous build).
        sh 'chmod -R -f a=rwx ./'
    }

    // Allow including extra environment variables to the container
    envVars = params.envVars + envVars

    withCredentials([string(credentialsId: 'github_packages_token', variable: 'GITHUB_NPM_TOKEN')]) {
        dockerRun (
            imageTag: "node${nodeVersion}",
            envVars: envVars,
            user: params.user,
            workdir: "/var/app",
            volumes: ["\$(pwd):/var/app"],
            script: params.script
        )
    }
}
def getNodeVersionFromNvmrc() {
    def path = findNvmrcFile()
    return path ? readFile(path)?.trim() : null
}

def getParentDir(String path) {
    def lastSlashIndex = path.lastIndexOf('/')
    return lastSlashIndex > 0 ? path.substring(0, lastSlashIndex) : null
}

def findNvmrcFile() {
    def currentDir = pwd()

    def currentPath = getNvmrcFilePath(currentDir)
    if (currentPath) return currentPath

    def rootDir = env.WORKSPACE // Jenkins workspace path

    while (currentDir != rootDir) {
        currentDir = getParentDir(currentDir)
        if (!currentDir) break 

        def filePath = getNvmrcFilePath(currentDir)
        if (filePath) return filePath
    }

    return getNvmrcFilePath(rootDir)
}

def getNvmrcFilePath(String dir) {
    println("Looking for .nvmrc file in: $dir")
    def filePath = "${dir}/.nvmrc"

    if (fileExists(filePath)) {
        println("Found $filePath")
        return filePath
    }

    return null
}
