"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.stillCommand = exports.STILL_COMMAND = void 0;
const cli_1 = require("@remotion/cli");
const config_1 = require("@remotion/cli/config");
const lambda_client_1 = require("@remotion/lambda-client");
const constants_1 = require("@remotion/lambda-client/constants");
const renderer_1 = require("@remotion/renderer");
const client_1 = require("@remotion/renderer/client");
const serverless_1 = require("@remotion/serverless");
const path_1 = __importDefault(require("path"));
const no_react_1 = require("remotion/no-react");
const download_media_1 = require("../../api/download-media");
const validate_retries_1 = require("../../shared/validate-retries");
const args_1 = require("../args");
const get_aws_region_1 = require("../get-aws-region");
const find_function_name_1 = require("../helpers/find-function-name");
const quit_1 = require("../helpers/quit");
const log_1 = require("../log");
const progress_1 = require("./render/progress");
const { offthreadVideoCacheSizeInBytesOption, offthreadVideoThreadsOption, scaleOption, deleteAfterOption, jpegQualityOption, enableMultiprocessOnLinuxOption, glOption, headlessOption, delayRenderTimeoutInMillisecondsOption, binariesDirectoryOption, mediaCacheSizeInBytesOption, darkModeOption, } = client_1.BrowserSafeApis.options;
const { parsedCli, determineFinalStillImageFormat, chalk, getCliOptions, formatBytes, getCompositionWithDimensionOverride, } = cli_1.CliInternals;
exports.STILL_COMMAND = 'still';
const stillCommand = async ({ args, remotionRoot, logLevel, providerSpecifics, }) => {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
    const serveUrl = args[0];
    if (!serveUrl) {
        log_1.Log.error({ indent: false, logLevel }, 'No serve URL passed.');
        log_1.Log.info({ indent: false, logLevel }, 'Pass an additional argument specifying a URL where your Remotion project is hosted.');
        log_1.Log.info({ indent: false, logLevel });
        log_1.Log.info({ indent: false, logLevel }, `${constants_1.BINARY_NAME} ${exports.STILL_COMMAND} <serve-url> <composition-id>  [output-location]`);
        (0, quit_1.quit)(1);
    }
    const { envVariables, inputProps, stillFrame, height, width, browserExecutable, userAgent, disableWebSecurity, ignoreCertificateErrors, } = getCliOptions({
        isStill: true,
        logLevel,
        indent: false,
    });
    const region = (0, get_aws_region_1.getAwsRegion)();
    let composition = args[1];
    const enableMultiProcessOnLinux = enableMultiprocessOnLinuxOption.getValue({
        commandLine: parsedCli,
    }).value;
    const gl = glOption.getValue({ commandLine: parsedCli }).value;
    const headless = headlessOption.getValue({
        commandLine: parsedCli,
    }).value;
    const darkMode = darkModeOption.getValue({ commandLine: parsedCli }).value;
    const chromiumOptions = {
        disableWebSecurity,
        enableMultiProcessOnLinux,
        gl,
        headless,
        ignoreCertificateErrors,
        userAgent,
        darkMode,
    };
    const timeoutInMilliseconds = delayRenderTimeoutInMillisecondsOption.getValue({
        commandLine: parsedCli,
    }).value;
    const offthreadVideoCacheSizeInBytes = offthreadVideoCacheSizeInBytesOption.getValue({
        commandLine: parsedCli,
    }).value;
    const offthreadVideoThreads = offthreadVideoThreadsOption.getValue({
        commandLine: parsedCli,
    }).value;
    const binariesDirectory = binariesDirectoryOption.getValue({
        commandLine: parsedCli,
    }).value;
    const mediaCacheSizeInBytes = mediaCacheSizeInBytesOption.getValue({
        commandLine: parsedCli,
    }).value;
    if (!composition) {
        log_1.Log.info({ indent: false, logLevel }, 'No compositions passed. Fetching compositions...');
        lambda_client_1.LambdaClientInternals.validateServeUrl(serveUrl);
        if (!serveUrl.startsWith('https://') && !serveUrl.startsWith('http://')) {
            throw Error('Passing the shorthand serve URL without composition name is currently not supported.\n Make sure to pass a composition name after the shorthand serve URL or pass the complete serveURL without composition name to get to choose between all compositions.');
        }
        const server = await renderer_1.RenderInternals.prepareServer({
            offthreadVideoThreads: 1,
            indent: false,
            port: config_1.ConfigInternals.getRendererPortFromConfigFileAndCliFlag(),
            remotionRoot,
            logLevel,
            webpackConfigOrServeUrl: serveUrl,
            offthreadVideoCacheSizeInBytes,
            binariesDirectory,
            forceIPv4: false,
        });
        const indent = false;
        const { compositionId } = await getCompositionWithDimensionOverride({
            args: args.slice(1),
            compositionIdFromUi: null,
            indent,
            serveUrlOrWebpackUrl: serveUrl,
            logLevel,
            browserExecutable,
            chromiumOptions,
            envVariables,
            serializedInputPropsWithCustomSchema: no_react_1.NoReactInternals.serializeJSONWithSpecialTypes({
                indent: undefined,
                staticBase: null,
                data: inputProps,
            }).serializedString,
            port: config_1.ConfigInternals.getRendererPortFromConfigFileAndCliFlag(),
            puppeteerInstance: undefined,
            timeoutInMilliseconds,
            height,
            width,
            server,
            offthreadVideoCacheSizeInBytes,
            offthreadVideoThreads,
            binariesDirectory,
            onBrowserDownload: cli_1.CliInternals.defaultBrowserDownloadProgress({
                indent,
                logLevel,
                quiet: cli_1.CliInternals.quietFlagProvided(),
                onProgress: () => undefined,
            }),
            chromeMode: 'headless-shell',
            mediaCacheSizeInBytes: mediaCacheSizeInBytes,
        });
        composition = compositionId;
    }
    const downloadName = (_a = args[2]) !== null && _a !== void 0 ? _a : null;
    const outName = args_1.parsedLambdaCli['out-name'];
    const functionName = await (0, find_function_name_1.findFunctionName)({ logLevel, providerSpecifics });
    const maxRetries = (_b = args_1.parsedLambdaCli['max-retries']) !== null && _b !== void 0 ? _b : constants_1.DEFAULT_MAX_RETRIES;
    (0, validate_retries_1.validateMaxRetries)(maxRetries);
    const privacy = (_c = args_1.parsedLambdaCli.privacy) !== null && _c !== void 0 ? _c : constants_1.DEFAULT_OUTPUT_PRIVACY;
    (0, serverless_1.validatePrivacy)(privacy, true);
    const { format: imageFormat, source: imageFormatReason } = determineFinalStillImageFormat({
        downloadName,
        outName: outName !== null && outName !== void 0 ? outName : null,
        cliFlag: (_d = parsedCli['image-format']) !== null && _d !== void 0 ? _d : null,
        isLambda: true,
        fromUi: null,
        configImageFormat: (_e = config_1.ConfigInternals.getUserPreferredStillImageFormat()) !== null && _e !== void 0 ? _e : null,
    });
    log_1.Log.info({ indent: false, logLevel }, cli_1.CliInternals.chalk.gray(`Function: ${cli_1.CliInternals.makeHyperlink({ text: functionName, fallback: functionName, url: `https://${(0, get_aws_region_1.getAwsRegion)()}.console.aws.amazon.com/lambda/home#/functions/${functionName}?tab=code` })}`));
    log_1.Log.info({ indent: false, logLevel }, cli_1.CliInternals.chalk.gray(`Image Format = ${imageFormat} (${imageFormatReason})`));
    const deleteAfter = args_1.parsedLambdaCli[deleteAfterOption.cliFlag];
    const scale = scaleOption.getValue({
        commandLine: parsedCli,
    }).value;
    const jpegQuality = jpegQualityOption.getValue({
        commandLine: parsedCli,
    }).value;
    const res = await lambda_client_1.LambdaClientInternals.internalRenderStillOnLambda({
        functionName,
        serveUrl,
        inputProps,
        imageFormat,
        composition,
        privacy,
        region,
        maxRetries,
        envVariables,
        frame: stillFrame,
        jpegQuality,
        logLevel,
        outName: outName !== null && outName !== void 0 ? outName : null,
        chromiumOptions,
        timeoutInMilliseconds,
        scale,
        forceHeight: height,
        forceWidth: width,
        onInit: ({ cloudWatchLogs, lambdaInsightsUrl }) => {
            log_1.Log.verbose({ indent: false, logLevel }, `${cli_1.CliInternals.makeHyperlink({
                text: 'CloudWatch Logs',
                url: cloudWatchLogs,
                fallback: `CloudWatch Logs: ${cloudWatchLogs}`,
            })} (if enabled)`);
            log_1.Log.verbose({ indent: false, logLevel }, `${cli_1.CliInternals.makeHyperlink({
                text: 'Lambda Insights',
                url: lambdaInsightsUrl,
                fallback: `Lambda Insights: ${lambdaInsightsUrl}`,
            })} (if enabled)`);
        },
        deleteAfter: deleteAfter !== null && deleteAfter !== void 0 ? deleteAfter : null,
        storageClass: (_f = args_1.parsedLambdaCli['storage-class']) !== null && _f !== void 0 ? _f : null,
        apiKey: (_g = args_1.parsedLambdaCli[client_1.BrowserSafeApis.options.apiKeyOption.cliFlag]) !== null && _g !== void 0 ? _g : null,
        licenseKey: (_h = args_1.parsedLambdaCli[client_1.BrowserSafeApis.options.licenseKeyOption.cliFlag]) !== null && _h !== void 0 ? _h : null,
        downloadBehavior: { type: 'play-in-browser' },
        forceBucketName: (_j = args_1.parsedLambdaCli['force-bucket-name']) !== null && _j !== void 0 ? _j : null,
        forcePathStyle: (_k = args_1.parsedLambdaCli['force-path-style']) !== null && _k !== void 0 ? _k : false,
        indent: false,
        offthreadVideoCacheSizeInBytes,
        offthreadVideoThreads: null,
        requestHandler: null,
        mediaCacheSizeInBytes,
    });
    log_1.Log.info({ indent: false, logLevel }, cli_1.CliInternals.chalk.gray(`Render ID: ${cli_1.CliInternals.makeHyperlink({ text: res.renderId, fallback: res.renderId, url: lambda_client_1.LambdaClientInternals.getS3RenderUrl({ bucketName: res.bucketName, renderId: res.renderId, region: (0, get_aws_region_1.getAwsRegion)() }) })}`));
    log_1.Log.info({ indent: false, logLevel }, cli_1.CliInternals.chalk.gray(`Bucket: ${cli_1.CliInternals.makeHyperlink({ text: res.bucketName, fallback: res.bucketName, url: `https://${(0, get_aws_region_1.getAwsRegion)()}.console.aws.amazon.com/s3/buckets/${res.bucketName}/?region=${(0, get_aws_region_1.getAwsRegion)()}` })}`));
    const artifactProgress = (0, progress_1.makeArtifactProgress)(res.artifacts);
    if (artifactProgress) {
        log_1.Log.info({
            indent: false,
            logLevel,
        }, (0, progress_1.makeArtifactProgress)(res.artifacts));
    }
    log_1.Log.info({ indent: false, logLevel }, chalk.blue('+ S3'.padEnd(cli_1.CliInternals.LABEL_WIDTH)), chalk.blue(cli_1.CliInternals.makeHyperlink({
        fallback: res.url,
        url: res.url,
        text: res.outKey,
    })), chalk.gray(formatBytes(res.sizeInBytes)));
    if (downloadName) {
        const { outputPath, sizeInBytes } = await (0, download_media_1.internalDownloadMedia)({
            bucketName: res.bucketName,
            outPath: downloadName,
            region,
            renderId: res.renderId,
            logLevel,
            providerSpecifics: providerSpecifics,
            forcePathStyle: args_1.parsedLambdaCli['force-path-style'],
        });
        const relativePath = path_1.default.relative(process.cwd(), outputPath);
        log_1.Log.info({ indent: false, logLevel }, chalk.blue('↓'.padEnd(cli_1.CliInternals.LABEL_WIDTH)), chalk.blue(cli_1.CliInternals.makeHyperlink({
            url: 'file://' + outputPath,
            text: relativePath,
            fallback: outputPath,
        })), chalk.gray(formatBytes(sizeInBytes)));
    }
};
exports.stillCommand = stillCommand;
