"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RunEnv = void 0;
const tslib_1 = require("tslib");
const path_1 = require("path");
const os_1 = require("os");
const promises_1 = require("fs/promises");
const glob_1 = (0, tslib_1.__importDefault)(require("glob"));
const docker_1 = require("../utils/docker");
const exec_1 = require("./exec");
const scripts_1 = require("./scripts");
const error_1 = require("../utils/error");
const schema_1 = require("../generated/schema");
const assert_never_1 = require("../utils/assert-never");
const getSecret = (name) => { var _a; return (_a = process.env[`SECRET_${name}`]) !== null && _a !== void 0 ? _a : (0, error_1.error)(`Secret "${name}" is not defined`); };
class RunEnv {
    constructor(graph, api) {
        this.graph = graph;
        this.api = api;
        this.docker = false;
        this.cwd = (0, path_1.resolve)((0, os_1.tmpdir)(), this.graph.job.id, this.graph.job.repo.slug);
    }
    async init() {
        await (0, promises_1.mkdir)(this.cwd, { recursive: true });
    }
    async clean() {
        await Promise.all([
            (0, promises_1.rm)(this.cwd, { recursive: true }),
            Promise.resolve().then(() => {
                if (this.docker) {
                    return docker_1.docker.kill(this.graph.job.id);
                }
            }),
        ]);
    }
    async exec(node, output) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        const { job } = this.graph;
        const { step } = node;
        const pathEnv = process.platform === 'win32' ? 'Path' : 'PATH';
        const env = {
            PWD: this.cwd,
            SHELL: process.env.SHELL,
            HOME: process.env.HOME,
            [pathEnv]: (_a = process.env[pathEnv]) !== null && _a !== void 0 ? _a : '',
        };
        for (const { name, value, secret } of step.env) {
            env[name] = secret ? getSecret(value) : value;
        }
        let command = step.command;
        const init = command[0] === '@refloat/init';
        const skip = command[0] === '@refloat/init-no-checkout';
        const artifact = command[0] === '@refloat/artifact';
        if (skip) {
            output === null || output === void 0 ? void 0 : output(Buffer.from('Repository checkout skipped\n'));
            return 0;
        }
        if (artifact) {
            const { cwd } = this;
            const matches = await Promise.all(command.slice(1).map((file) => new Promise((resolve, reject) => {
                (0, glob_1.default)(file, { cwd, nonull: true }, (err, result) => err ? reject(err) : resolve(result));
            })));
            const files = Array.from(new Set(matches.flat()));
            await Promise.all(files.map((path) => this.api.upload({
                stepId: step.id,
                cwd,
                path,
            })));
            const text = 'Uploaded artifacts:' + files.map((file) => `- ${file}`).join('\n');
            output === null || output === void 0 ? void 0 : output(Buffer.from(text));
            return 0;
        }
        if (init) {
            const { providerType, providerSource } = job.repo;
            if (providerType === schema_1.RepoProviderType.Custom &&
                providerSource === 'refloat.io/script') {
                return 0;
            }
            command = [scripts_1.scripts.init];
            Object.assign(env, {
                REFLOAT_CLONE_URL: providerType === schema_1.RepoProviderType.GitHub
                    ? `git@github.com:${providerSource}.git`
                    : providerType === schema_1.RepoProviderType.Bitbucket
                        ? `git@bitbucket.org:${providerSource}.git`
                        : providerType === schema_1.RepoProviderType.Custom
                            ? providerSource
                            : (0, assert_never_1.assertNever)(providerType),
                REFLOAT_CLONE_SHA: job.build.sha,
                REFLOAT_CLONE_BRANCH: job.build.branch,
                REFLOAT_DOCKER_FILE: (_c = (_b = job.docker) === null || _b === void 0 ? void 0 : _b.file) !== null && _c !== void 0 ? _c : '',
                REFLOAT_DOCKER_IMAGE: (_e = (_d = job.docker) === null || _d === void 0 ? void 0 : _d.image) !== null && _e !== void 0 ? _e : '',
                REFLOAT_DOCKER_CONTEXT: (_g = (_f = job.docker) === null || _f === void 0 ? void 0 : _f.context) !== null && _g !== void 0 ? _g : '',
                REFLOAT_JOB_ID: job.id,
                REFLOAT_REPO_NAME: job.repo.slug,
            });
        }
        if (!init && (((_h = job.docker) === null || _h === void 0 ? void 0 : _h.image) || ((_j = job.docker) === null || _j === void 0 ? void 0 : _j.file))) {
            this.docker = true;
            command = [
                'docker',
                'exec',
                '-t',
                '-w',
                (0, path_1.resolve)('/refloat', job.repo.slug),
                ...step.env.flatMap((name) => ['-e', name.name]),
                job.id,
                ...command,
            ];
        }
        return (0, exec_1.exec)(command[0], command.slice(1), {
            env,
            cwd: this.cwd,
            output,
        });
    }
}
exports.RunEnv = RunEnv;
//# sourceMappingURL=run-env.js.map