import fs from 'fs';
import path from 'path';
import { z } from 'zod';
import { globalOptionsZod } from '../../../../Command.js';
import request from '../../../../request.js';
import { formatting } from '../../../../utils/formatting.js';
import PowerAppsCommand from '../../../base/PowerAppsCommand.js';
import flowCommands from '../../../flow/commands.js';
import commands from '../../commands.js';
export const options = z.strictObject({
    ...globalOptionsZod.shape,
    environmentName: z.string().alias('e'),
    name: z.string().alias('n'),
    outputFolder: z.string().optional()
});
class PaConnectorExportCommand extends PowerAppsCommand {
    get name() {
        return commands.CONNECTOR_EXPORT;
    }
    get description() {
        return 'Exports the specified power automate or power apps custom connector';
    }
    alias() {
        return [flowCommands.CONNECTOR_EXPORT];
    }
    get schema() {
        return options;
    }
    getRefinedSchema(schema) {
        return schema
            .refine(opts => !opts.outputFolder || fs.existsSync(path.resolve(opts.outputFolder)), {
            message: `Specified output folder doesn't exist.`
        })
            .refine(opts => !fs.existsSync(path.resolve(opts.outputFolder || '.', opts.name)), {
            message: 'Connector output folder already exists.'
        });
    }
    async commandAction(logger, args) {
        const outputFolder = path.resolve(args.options.outputFolder || '.', args.options.name);
        const requestOptions = {
            url: `${this.resource}/providers/Microsoft.PowerApps/apis/${formatting.encodeQueryParameter(args.options.name)}?api-version=2016-11-01&$filter=environment%20eq%20%27${formatting.encodeQueryParameter(args.options.environmentName)}%27%20and%20IsCustomApi%20eq%20%27True%27`,
            headers: {
                accept: 'application/json'
            },
            responseType: 'json'
        };
        let connector;
        if (this.verbose) {
            await logger.logToStderr('Downloading connector...');
        }
        try {
            connector = await request.get(requestOptions);
            if (!connector.properties) {
                throw 'Properties not present in the api registration information.';
            }
            if (this.verbose) {
                await logger.logToStderr(`Creating output folder ${outputFolder}...`);
            }
            fs.mkdirSync(outputFolder);
            const settings = {
                apiDefinition: "apiDefinition.swagger.json",
                apiProperties: "apiProperties.json",
                connectorId: args.options.name,
                environment: args.options.environmentName,
                icon: "icon.png",
                powerAppsApiVersion: "2016-11-01",
                powerAppsUrl: "https://api.powerapps.com"
            };
            if (this.verbose) {
                await logger.logToStderr('Exporting settings...');
            }
            fs.writeFileSync(path.join(outputFolder, 'settings.json'), JSON.stringify(settings, null, 2), 'utf8');
            const propertiesWhitelist = [
                "connectionParameters",
                "iconBrandColor",
                "capabilities",
                "policyTemplateInstances"
            ];
            const apiProperties = {
                properties: JSON.parse(JSON.stringify(connector.properties))
            };
            Object.keys(apiProperties.properties).forEach(k => {
                if (propertiesWhitelist.indexOf(k) < 0) {
                    delete apiProperties.properties[k];
                }
            });
            if (this.verbose) {
                await logger.logToStderr('Exporting API properties...');
            }
            fs.writeFileSync(path.join(outputFolder, 'apiProperties.json'), JSON.stringify(apiProperties, null, 2), 'utf8');
            let swagger = '';
            if (connector.properties.apiDefinitions &&
                connector.properties.apiDefinitions.originalSwaggerUrl) {
                if (this.verbose) {
                    await logger.logToStderr(`Downloading swagger from ${connector.properties.apiDefinitions.originalSwaggerUrl}...`);
                }
                swagger = await request
                    .get({
                    url: connector.properties.apiDefinitions.originalSwaggerUrl,
                    headers: {
                        'x-anonymous': 'true'
                    }
                });
            }
            else {
                if (this.debug) {
                    await logger.logToStderr('originalSwaggerUrl not set. Skipping');
                }
            }
            if (swagger && swagger.length > 0) {
                if (this.debug) {
                    await logger.logToStderr('Downloaded swagger');
                    await logger.logToStderr(swagger);
                }
                if (this.verbose) {
                    await logger.logToStderr('Exporting swagger...');
                }
                fs.writeFileSync(path.join(outputFolder, 'apiDefinition.swagger.json'), swagger, 'utf8');
            }
            let icon = '';
            if (connector.properties.iconUri) {
                if (this.verbose) {
                    await logger.logToStderr(`Downloading icon from ${connector.properties.iconUri}...`);
                }
                icon = await request
                    .get({
                    url: connector.properties.iconUri,
                    responseType: 'arraybuffer',
                    headers: {
                        'x-anonymous': 'true'
                    }
                });
            }
            else {
                if (this.debug) {
                    await logger.logToStderr('iconUri not set. Skipping');
                }
            }
            if (icon) {
                if (this.verbose) {
                    await logger.logToStderr('Exporting icon...');
                }
                const iconBuffer = Buffer.from(icon, 'utf8');
                fs.writeFileSync(path.join(outputFolder, 'icon.png'), iconBuffer);
            }
            else {
                if (this.debug) {
                    await logger.logToStderr('No icon retrieved');
                }
            }
        }
        catch (err) {
            this.handleRejectedODataJsonPromise(err);
        }
    }
}
export default new PaConnectorExportCommand();
//# sourceMappingURL=connector-export.js.map