"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPvcFileStore = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const YAML = require("yaml");
const _ = require("lodash");
const contracts_1 = require("../../apis/codiac-api/contracts");
const command_base_exec_1 = require("../../command-base-exec");
const prettify_1 = require("../../prettify");
const output_format_enum_1 = require("../../cli-entities/output-format-enum");
const type_safety_utils_1 = require("../../uilogic/type-safety-utils");
const list_1 = require("../filestore/list");
/** FileStoreDef types whose volume access semantics REQUIRE a PVC. Mirrors
 *  K8sFileStoreRouter.PVC_NATIVE_TYPES on the relay side. */
const PVC_NATIVE_TYPES = new Set([
    contracts_1.FileStoreTypeEnum.azureDisk,
    contracts_1.FileStoreTypeEnum.azureBlobStorage,
    contracts_1.FileStoreTypeEnum.azureNetAppFiles,
    contracts_1.FileStoreTypeEnum.awsEbs,
]);
/** Returns true when the FileStoreDef is provisioned via PersistentVolumeClaim
 *  (vs the legacy inline CSI path). Mirrors K8sFileStoreRouter.isPvcFilestore on
 *  the relay side. */
function isPvcFileStore(fs) {
    var _a;
    if (PVC_NATIVE_TYPES.has(fs.type))
        return true;
    if (fs.storageClass)
        return true;
    if (fs.volumeName)
        return true;
    if (fs.storageRequest)
        return true;
    if (fs.accessModes && fs.accessModes.length > 0)
        return true;
    // Legacy POC convention: AzureFileStorage with shareName starting "pvc-".
    if (fs.type === contracts_1.FileStoreTypeEnum.azureFileStorage && ((_a = fs.shareName) === null || _a === void 0 ? void 0 : _a.startsWith('pvc-')))
        return true;
    return false;
}
exports.isPvcFileStore = isPvcFileStore;
class PvcList extends command_base_exec_1.CommandBaseExec {
    captureArgs() {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { flags } = yield this.parse(PvcList);
            const partial = {};
            if (flags.enterprise)
                partial.enterprise = flags.enterprise;
            if (flags.type)
                partial.type = type_safety_utils_1.TypeSafetyUtils.toEnum(contracts_1.FileStoreTypeEnum, flags.type);
            if (flags.output)
                partial.outputFormat = type_safety_utils_1.TypeSafetyUtils.toEnum(output_format_enum_1.OutputFormatEnum, flags.output);
            const takeDefaults = (_a = flags['take-defaults']) !== null && _a !== void 0 ? _a : false;
            return [partial, takeDefaults];
        });
    }
    buildCandidate_silently(partial, rootMap) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const candidate = {
                enterprise: partial.enterprise,
                outputFormat: (_a = partial.outputFormat) !== null && _a !== void 0 ? _a : output_format_enum_1.OutputFormatEnum.auto,
            };
            if (partial.type)
                candidate.type = partial.type;
            if (!candidate.type)
                candidate.all = true;
            return candidate;
        });
    }
    buildCandidate_interactively(partial, rootMap, takeDefaults) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return this.buildCandidate_silently(partial, rootMap);
        });
    }
    buildCommandString(candidate, cmd) {
        if (candidate.type)
            cmd.push("--type", candidate.type.toString());
        if (candidate.outputFormat)
            cmd.push("-o", candidate.outputFormat);
        cmd.push("--silent");
        return cmd;
    }
    executeTask(candidate) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const req = Object.assign({}, _.omit(candidate, "enterprise", "outputFormat"));
            const list = yield this._codiacApi.FileStoreDef.readMany(req);
            // The criteria DSL doesn't express "is PVC-backed" cleanly, so filter client-side
            // using the same predicate the relay router uses to route between PVC and inline CSI.
            const pvcOnly = list.filter(isPvcFileStore);
            const output = this.renderAs(pvcOnly, candidate.outputFormat, entity => list_1.FileStoreUiLogic.displayNameFor(entity, this._styler));
            console.log(output);
        });
    }
    renderAs(list, format, textFormatter) {
        let output = "";
        switch (format) {
            case output_format_enum_1.OutputFormatEnum.json:
                output = JSON.stringify(list, undefined, 2);
                break;
            case output_format_enum_1.OutputFormatEnum.yaml:
                output = YAML.stringify(list, { indent: 2 });
                break;
            case output_format_enum_1.OutputFormatEnum.pretty:
            case output_format_enum_1.OutputFormatEnum.auto:
            default:
                if (list.length > 0) {
                    output = textFormatter ? list.map(x => textFormatter(x)).join("\n") : (0, prettify_1.prettify)(list);
                }
                else {
                    output = "None found.";
                }
                break;
        }
        return output;
    }
}
exports.default = PvcList;
PvcList.description = 'Lists the PersistentVolumeClaim-backed filestore definitions for a given enterprise.';
PvcList.aliases = ['pvc:list'];
PvcList.examples = [
    '<%= config.bin %> <%= command.id %>',
    '<%= config.bin %> <%= command.id %> --type AzureBlobStorage',
    '<%= config.bin %> <%= command.id %> -o yaml',
];
PvcList.flags = {
    help: core_1.Flags.help({ char: 'h' }),
    enterprise: core_1.Flags.string({ char: 'e', description: 'Code name identifying the enterprise (optional if there is only one).' }),
    type: core_1.Flags.string({ char: 't', options: Object.values(contracts_1.FileStoreTypeEnum), required: false, description: 'Filter on the storage technology backing the PVC.' }),
    output: core_1.Flags.string({ char: 'o', default: output_format_enum_1.OutputFormatEnum.auto, description: 'Format in which to render the data.', options: [output_format_enum_1.OutputFormatEnum.json, output_format_enum_1.OutputFormatEnum.yaml, output_format_enum_1.OutputFormatEnum.auto] }),
    silent: core_1.Flags.boolean({ exclusive: ["echo", "to-script"], description: 'Non-Interactive mode; executes without any user interaction and fails on any missing or invalid arguments.' }),
    echo: core_1.Flags.boolean({ exclusive: ["to-script", "silent"], description: 'Echo interaction mode; renders the equivalent non-interactive cli command for future use before final execution.' }),
    "to-script": core_1.Flags.boolean({ exclusive: ["echo", "silent"], description: 'Toscript interaction mode; renders the equivalent non-interactive cli command WITHOUT any execution.' }),
    "take-defaults": core_1.Flags.boolean({ exclusive: ["silent"], description: "Setting this to true prevents prompting for confirmation on parameters that were passed in or were automatically set to default values (Irrelevant in --silent mode)." }),
};
//# sourceMappingURL=list.js.map