"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.configAgent = void 0;
const logger_1 = require("@refloat/logger");
const schema_1 = require("../generated/schema");
const run_1 = require("../modules/run");
const server_1 = require("../modules/server");
const error_1 = require("../utils/error");
const sleep_1 = require("../utils/sleep");
const logger = logger_1.Logger.create('config-agent');
async function configAgent(ctx, api) {
    var _a, _b, _c, _d;
    const modules = await (0, server_1.bootModuleServer)();
    try {
        while (ctx.running) {
            const build = await api.acquireBuild();
            if (!build) {
                await ctx.wait((0, sleep_1.sleep)(1000));
                continue;
            }
            let sha = null;
            try {
                logger.info('compiling configuration', { build: build.path });
                const start = Date.now();
                const overrides = {};
                const path = `${origin(build.repo, build.sha === 'HEAD' ? build.branch : build.sha)}/.refloat/config.js`;
                await modules.checkout(path);
                const [configSha, configSource] = await Promise.all([
                    modules.sha(path),
                    modules.get(path),
                ]);
                sha = configSha;
                if (!configSource) {
                    logger.warn('no config file found', { build: build.path });
                    await api.configureBuildError(build.id, 'No configuration file was found on .refloat/config.js', { sha, notFound: true });
                    continue;
                }
                if (build.dependencyOf) {
                    overrides[origin(build.dependencyOf.repo)] = origin(build.dependencyOf.repo, build.dependencyOf.sha);
                }
                const { dependencies, config } = await (0, run_1.runConfig)(path, configSource, modules.checkout, async (file) => {
                    const contents = await modules.get(file);
                    if (contents === null) {
                        throw new Error(`file "${file}" not found`);
                    }
                    else {
                        return contents;
                    }
                }, {
                    org: {
                        id: build.repo.org.id,
                        slug: build.repo.org.slug,
                    },
                    user: {
                        id: build.user.id,
                        displayName: build.user.displayName,
                    },
                    repo: {
                        id: build.repo.id,
                        slug: build.repo.slug,
                        defaultBranch: build.repo.defaultBranch,
                    },
                    build: {
                        id: build.id,
                        number: build.number,
                    },
                    commit: {
                        sha,
                        branch: build.branch,
                        defaultBranch: build.branch === build.repo.defaultBranch,
                    },
                }, overrides);
                logger.info('configuration compiled', {
                    build: build.path,
                    duration: `${Date.now() - start}ms`,
                });
                await api.configureBuild(build.id, sha, dependencies, config);
            }
            catch (error) {
                error = (_c = (_b = (_a = error === null || error === void 0 ? void 0 : error.networkError) === null || _a === void 0 ? void 0 : _a.result) !== null && _b !== void 0 ? _b : error) !== null && _c !== void 0 ? _c : 'Undefined error';
                logger.error('config job error', { error });
                try {
                    await api.configureBuildError(build.id, String((_d = error === null || error === void 0 ? void 0 : error.message) !== null && _d !== void 0 ? _d : error), { sha });
                }
                catch (error) {
                    logger.error('failed to notify server about config error', { error });
                }
            }
        }
    }
    finally {
        await modules.close();
    }
}
exports.configAgent = configAgent;
const origin = (repo, sha) => `${repo.providerType === schema_1.RepoProviderType.GitHub
    ? `git+ssh://github.com/${repo.providerSource}`
    : repo.providerType === schema_1.RepoProviderType.Bitbucket
        ? `git+ssh://bitbucket.org/${repo.providerSource}`
        : repo.providerType === schema_1.RepoProviderType.Custom
            ? httpsRe.test(repo.providerSource)
                ? `git+https://${repo.providerSource.replace(httpsRe, '')}`
                : (0, error_1.error)(`unsupported repository source: "${repo.providerSource}"`)
            : (0, error_1.error)(`unexpected providerType: "${repo.providerType}"`)}${sha ? '#' + sha : ''}`;
const httpsRe = /^https:\/\//i;
//# sourceMappingURL=config-agent.js.map