"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mablApiClientFactory_1 = require("@mablhq-internal/runtime/api/mablApiClientFactory");
const cliUtil_1 = require("@mablhq-internal/runtime/core/cliUtil");
const constants_1 = require("../../constants");
const loggingProvider_1 = require("@mablhq-internal/runtime/providers/logging/loggingProvider");
const chalk_1 = __importDefault(require("chalk"));
const moment_1 = __importDefault(require("moment"));
const inquirer_1 = __importDefault(require("inquirer"));
const mablApi_1 = require("@mablhq-internal/runtime/mablApi");
const ora = require("ora");
exports.command = 'copy';
exports.describe = 'copy data from one workspace to another';
exports.builder = (yargs) => {
    yargs
        .option(constants_1.CommandArgFrom, {
        describe: 'The workspace from which to copy',
        required: true,
        nargs: 1,
    })
        .option(constants_1.CommandArgTo, {
        describe: 'The workspace the data will be copied into',
        required: true,
        nargs: 1,
    })
        .option(constants_1.CommandArgIncludeDefaults, {
        describe: 'Include default tests when copying',
        default: false,
        type: 'boolean',
    })
        .option(constants_1.CommandArgIncludedTests, {
        describe: 'List of test ids to include with the copy. If empty, all tests will be copied.',
        default: [],
        type: 'array',
    })
        .option(constants_1.CommandArgExcludedTests, {
        describe: 'List of test ids to exclude from the copy. If a test is in both the include and exclude list, it will be excluded.',
        default: [],
        type: 'array',
    });
};
exports.handler = (0, cliUtil_1.failWrapper)(copyWorkspace);
function getTimestamp() {
    return (0, moment_1.default)().format('HH:mm:ss');
}
function hasOwnerRoleInWorkspace(user, workspaceId) {
    const hasOwnerRole = user.roles?.some((role) => role.organization_id === workspaceId && role.role === mablApi_1.UserRoleEnum.Owner);
    if (!hasOwnerRole) {
        loggingProvider_1.logger.warn(chalk_1.default.yellow(`You must be an owner in both workspaces to copy. You do not have owner permissions in workspace: ${workspaceId}`));
    }
    return !!hasOwnerRole;
}
async function copyWorkspace(parsed) {
    const spinner = ora({
        prefixText: ' ',
        text: 'Copying workspace assets...',
    });
    try {
        const sourceWorkspaceId = parsed.from;
        const destinationWorkspaceId = parsed.to;
        const includeDefaults = parsed.includeDefaults;
        const includedTests = parsed.includedTests;
        const excludedTests = parsed.excludedTests;
        const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
        const [sourceWorkspace, destinationWorkspace] = await Promise.all([
            apiClient.getWorkspace(sourceWorkspaceId),
            apiClient.getWorkspace(destinationWorkspaceId),
        ]);
        const user = await apiClient.getSelf();
        if (!hasOwnerRoleInWorkspace(user, sourceWorkspaceId) ||
            !hasOwnerRoleInWorkspace(user, destinationWorkspaceId)) {
            return Promise.reject(new Error('You must be owner of both the source and destination workspace to copy a workspace.'));
        }
        loggingProvider_1.logger.info(chalk_1.default.yellow(`[${getTimestamp()}] In case of failure, please DO NOT re-run this command, as it would create duplicate items in the destination. The operation may take several minutes, or longer for especially large workspaces. Please contact mabl support if you encounter any issues.`));
        loggingProvider_1.logger.info(chalk_1.default.yellow(`[${getTimestamp()}] Note: currently the copy includes tests, flows, datatables, file uploads, javascript snippets. Unsupported items include: plans, applications, environments, coverage, and run history.`));
        const excludedTestsConfirmationDetail = !includeDefaults || excludedTests?.length
            ? ' excluding default tests and all tests specified with --exclude-tests '
            : '';
        const specifiedOrAllTests = includedTests?.length ? 'specified' : 'ALL';
        const response = await inquirer_1.default.prompt([
            {
                type: 'confirm',
                name: 'do_continue',
                message: `Are you sure you want to copy ${specifiedOrAllTests} tests${excludedTestsConfirmationDetail} from Workspace [${sourceWorkspaceId}](${sourceWorkspace.name}) to Workspace [${destinationWorkspaceId}](${destinationWorkspace.name})? Once the copy begins, it cannot be cancelled.`,
                default: false,
            },
        ]);
        if (!response.do_continue) {
            return 'Skipped';
        }
        loggingProvider_1.logger.info(chalk_1.default.yellow(`[${getTimestamp()}] The copy process will complete even if this command is interrupted.`));
        spinner.start();
        await apiClient.copyWorkspace(sourceWorkspaceId, destinationWorkspaceId, includeDefaults, includedTests, excludedTests);
        spinner.succeed('Done copying assets');
        loggingProvider_1.logger.info(chalk_1.default.green(`[${getTimestamp()}] Workspace copy successful`));
        return 'Success';
    }
    catch (error) {
        if (spinner.isSpinning) {
            spinner.fail('Error copying workspace assets');
            loggingProvider_1.logger.info(chalk_1.default.red(`[${getTimestamp()}] Workspace copy failed`));
        }
        throw error;
    }
}
