"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const _ = require("lodash");
const command_base_tenantless_1 = require("../../command-base-tenantless");
class ImagesPatch extends command_base_tenantless_1.CommandBaseTenantless {
    run() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.bootstrap();
            const { args, flags } = yield this.parse(ImagesPatch);
            let imageName = args.imageName;
            if (this._projCfg.images && this._projCfg.images[imageName]) {
                let image = this._projCfg.images[imageName]; /* goddamn nullable dictionary */
                if (image) {
                    let exps = (flags.set) ? flags.set.split(" ") : [];
                    let unsets = (flags.unset) ? flags.unset.split(" ") : [];
                    if (exps.length == 0 && unsets.length == 0) {
                        this._ui.userMessage("No modifications were specified.  Use the --set and --unset arguments to apply changes.");
                        this._ui.userMessage("No work was done.");
                        this.exit();
                    }
                    else {
                        // DEV NOTE:  INTENDED DESIGN:
                        // 1) Construct json patch object and fire it against the api.
                        // 2) retrieve the current state of the ImageExport (aka: Asset) from the API,
                        //    using projections to match it with the entity in codiac.json
                        // 3) Write the retrieved, projected entity to codiac.json
                        // 4) A microservice needs to subscribe to change events of the
                        //    relevant domain entities to ensure the deployment entity is updated.
                        // 5) This command should wait for that change to propagate up there so
                        //    there's no inconsistency in a scripted sequence
                        //    that might otherwise fire before the upstream config object has been updated.
                        // INSTEAD,
                        // We're gonna write directly to the codiac.json
                        // and then manually update the toybox-deployment.json
                        // Sets
                        if (exps.length > 0) {
                            let patchObj = {};
                            for (let index in exps) {
                                let path = exps[index].split("=")[0];
                                let val = exps[index].split("=")[1];
                                // TODO: Strip out any property assignments that dont conform to ImageExport
                                //       (consider throwing error instead of continuing)
                                patchObj = _.set(patchObj, path, val); //NOTE:  This doesnt retain native types
                                if (path == "port")
                                    patchObj.port = parseInt(val);
                            }
                            this._projCfg.images[imageName] = _.assignIn(image, patchObj);
                            yield this.projCfgRepo.updateProjectConfigFile(this._projCfg);
                        }
                        // Unsets
                        if (unsets.length > 0) {
                            let modified = this._projCfg.images[imageName];
                            if (modified) {
                                for (let index in unsets) {
                                    let path = unsets[index];
                                    // TODO: Strip out any property assignments that dont conform to ImageExport
                                    //       (consider throwing error instead of continuing)
                                    _.unset(modified, path);
                                }
                                this._projCfg.images[imageName] = modified;
                                yield this.projCfgRepo.updateProjectConfigFile(this._projCfg);
                            }
                        }
                        this._ui.userMessage(`COMPLETE!  Patched image [${imageName}]`);
                    }
                }
                else {
                    // Goddamn nullable dictionary
                    this._ui.userMessage(`The image export named [${imageName}] is null.`);
                    this._ui.userMessage(`No work was done.`);
                }
            }
            else {
                this._ui.userMessage(`No image named [${imageName}] is configured as an export in this project.`);
                this._ui.userMessage(`No work was done.`);
            }
        });
    }
}
exports.default = ImagesPatch;
ImagesPatch.description = 'Applies the given values to an existing image export configuration.  Both registryUrl and environment act as filters to limit the operation.  That is, an upsert of registry targets is performed for the given image, based on the given registryUrl and/or environment.';
ImagesPatch.aliases = ["image:patch", "img:patch"];
ImagesPatch.flags = {
    help: core_1.Flags.help({ char: 'h' }),
    set: core_1.Flags.string({ char: 's', required: false, description: 'Space-delimited list of key-value pairs tp apply with json-path on the left and the desired value on the right.  (eg:  --set .targets.default.registryUrl=mystuff.azurecr.io)' }),
    unset: core_1.Flags.string({ char: 'u', required: false, description: 'Space-delimited list of properties to clear, in json-path format.  (eg:  --unset .targets.default)' }),
};
ImagesPatch.args = {
    imageName: core_1.Args.string({ required: true, description: 'image name including, scope prefix. eg:  "your-company/your-image"' })
};
//# sourceMappingURL=patch.js.map