"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RuntimeJavaVersionIdentifier = void 0;
exports._extractJavaVersionFrom = _extractJavaVersionFrom;
const semver_1 = require("semver");
const node_child_process_1 = __importDefault(require("node:child_process"));
class RuntimeJavaVersionIdentifier {
    cache = new Map();
    identifyJavaVersion(javaCommand) {
        if (this.cache.has(javaCommand)) {
            return Promise.resolve(this.cache.get(javaCommand));
        }
        return new Promise((resolve, reject) => {
            // We are using "java -version" which has output that typically looks like:
            // * (from MacOS): "openjdk version "11.0.6" 2020-01-14 LTS\nOpenJDK Runtime Environment Zulu11.37+17-CA (build 11.0.6+10-LTS)\nOpenJDK 64-Bit Server VM Zulu11.37+17-CA (build 11.0.6+10-LTS, mixed mode)\n"
            // From much research this output typically has the word "version " and then either a number with or without quotes.
            // If instead we used java --version then the output would look something like:
            // * (from Win10): "openjdk 14 2020-03-17\r\nOpenJDK Runtime Environment (build 14+36-1461)\r\nOpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)\r\n"
            // Notice it doesn't have the word "version" which is why we don't call "--version" but instead call "-version".
            const childProcess = node_child_process_1.default.spawn(javaCommand, ['-version']);
            let stderr = '';
            childProcess.stderr.on('data', (data) => {
                stderr += data.toString();
            });
            childProcess.on('exit', (code) => {
                /* istanbul ignore else */
                if (code === 0) {
                    // Oddly enough the -version command is documented to go to stderr and not stdout
                    const version = _extractJavaVersionFrom(stderr);
                    this.cache.set(javaCommand, version);
                    resolve(version);
                }
                else {
                    // A non-0 exit code indicates a failure. So just reject with whatever `stderr` was.
                    reject(stderr);
                }
            });
            childProcess.on('error', (err) => {
                reject(err.message);
            });
        });
    }
}
exports.RuntimeJavaVersionIdentifier = RuntimeJavaVersionIdentifier;
function _extractJavaVersionFrom(javaVersionOutput) {
    // First we'll see if the word "version" exists with the version number and use that first.
    const matchedParts = javaVersionOutput.match(/version\s+"?(\d+(\.\d+)*)"?/i);
    const versionString = matchedParts?.[1];
    if (versionString) {
        return (0, semver_1.coerce)(versionString);
    }
    // Otherwise we'll try to get the version number the crude way by just looking for the first number (which is what coerce does)
    return (0, semver_1.coerce)(javaVersionOutput);
}
//# sourceMappingURL=JavaVersionIdentifier.js.map