"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnumNamespace = void 0;
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
const linq_1 = require("@azure-tools/linq");
const codegen_csharp_1 = require("@azure-tools/codegen-csharp");
const powershell_declarations_1 = require("../internal/powershell-declarations");
const path_1 = require("path");
class EnumNamespace extends codegen_csharp_1.Namespace {
    get outputFolder() {
        return (0, path_1.join)(this.state.project.apiFolder, 'Support');
    }
    constructor(parent, state, objectInitializer) {
        var _a;
        super('Support', parent);
        this.state = state;
        this.apply(objectInitializer);
        //const enumInfos = [...state.model.schemas.sealedChoices ?? [], ...state.model.schemas.choices ?? []]
        const enumInfos = [...(_a = state.model.schemas.sealedChoices) !== null && _a !== void 0 ? _a : []]
            .filter((choice) => { var _a; return !((_a = choice.language.csharp) === null || _a === void 0 ? void 0 : _a.skip); })
            .map((choice) => {
            var _a, _b;
            return {
                details: (_a = choice.language.csharp) === null || _a === void 0 ? void 0 : _a.enum,
                description: (_b = choice.language.csharp) === null || _b === void 0 ? void 0 : _b.description
            };
        });
        const done = new Set();
        for (const enumInfo of enumInfos) {
            if (done.has(enumInfo.details.name)) {
                continue;
            }
            done.add(enumInfo.details.name);
            if (state.project.azure && /^api-?version$/i.exec(enumInfo.details.name)) {
                continue;
            }
            // generate a typeconverter for the enum class too.
            const enumValues = (0, linq_1.values)(enumInfo.details.values).select(v => v.value).toArray();
            const enumClass = new codegen_csharp_1.Struct(this, enumInfo.details.name, undefined, {
                interfaces: [powershell_declarations_1.IArgumentCompleter],
                partial: true,
                description: enumInfo.description || `Argument completer implementation for ${enumInfo.details.name}.`,
                fileName: `${enumInfo.details.name}.Completer`
            });
            const commandName = new codegen_csharp_1.Parameter('commandName', codegen_csharp_1.System.String, { description: 'The name of the command that needs argument completion.' });
            const parameterName = new codegen_csharp_1.Parameter('parameterName', codegen_csharp_1.System.String, { description: 'The name of the parameter that needs argument completion.' });
            const wordToComplete = new codegen_csharp_1.Parameter('wordToComplete', codegen_csharp_1.System.String, { description: 'The (possibly empty) word being completed.' });
            const commandAst = new codegen_csharp_1.Parameter('commandAst', powershell_declarations_1.CommandAst, { description: 'The command ast in case it is needed for completion.' });
            const fakeBoundParameters = new codegen_csharp_1.Parameter('fakeBoundParameters', codegen_csharp_1.System.Collections.IDictionary, { description: 'This parameter is similar to $PSBoundParameters, except that sometimes PowerShell cannot or will not attempt to evaluate an argument, in which case you may need to use commandAst.' });
            const completeArgumentParams = [commandName, parameterName, wordToComplete, commandAst, fakeBoundParameters];
            enumClass.add(new codegen_csharp_1.Method('CompleteArgument', codegen_csharp_1.System.Collections.Generic.IEnumerable(powershell_declarations_1.CompletionResult), { parameters: completeArgumentParams, description: 'Implementations of this function are called by PowerShell to complete arguments.', returnsDescription: 'A collection of completion results, most like with ResultType set to ParameterValue.' })).add(function* () {
                for (const enumValue of enumValues) {
                    yield (0, codegen_csharp_1.If)(`${codegen_csharp_1.System.String.declaration}.IsNullOrEmpty(${wordToComplete.name}) || "${enumValue}".StartsWith(${wordToComplete.name}, ${codegen_csharp_1.System.StringComparison.declaration}.InvariantCultureIgnoreCase)`, `yield return new ${powershell_declarations_1.CompletionResult.declaration}("'${enumValue}'", "${enumValue}", ${powershell_declarations_1.CompletionResultType.declaration}.ParameterValue, "${enumValue}");`);
                }
            });
            // generate a typeconverter for the enum class too.
            const converterClass = new codegen_csharp_1.Class(this, `${enumInfo.details.name}TypeConverter`, undefined, {
                interfaces: [powershell_declarations_1.PSTypeConverter],
                partial: true,
                description: enumInfo.description || `TypeConverter implementation for ${enumInfo.details.name}.`,
                fileName: `${enumInfo.details.name}.TypeConverter`
            });
            converterClass.add(new codegen_csharp_1.LambdaMethod('CanConvertFrom', codegen_csharp_1.dotnet.Bool, codegen_csharp_1.dotnet.True, {
                override: codegen_csharp_1.Modifier.Override,
                parameters: [
                    new codegen_csharp_1.Parameter('sourceValue', codegen_csharp_1.dotnet.Object, { description: 'the <see cref="System.Object"/> to convert from' }),
                    new codegen_csharp_1.Parameter('destinationType', codegen_csharp_1.System.Type, { description: 'the <see cref="System.Type" /> to convert to' })
                ],
                description: 'Determines if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType" /> parameter.',
                returnsDescription: '<c>true</c> if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType" /> parameter, otherwise <c>false</c>.',
            }));
            converterClass.add(new codegen_csharp_1.LambdaMethod('CanConvertTo', codegen_csharp_1.dotnet.Bool, codegen_csharp_1.dotnet.False, {
                override: codegen_csharp_1.Modifier.Override,
                parameters: [
                    new codegen_csharp_1.Parameter('sourceValue', codegen_csharp_1.dotnet.Object, { description: 'the <see cref="System.Object"/> to convert from' }),
                    new codegen_csharp_1.Parameter('destinationType', codegen_csharp_1.System.Type, { description: 'the <see cref="System.Type" /> to convert to' })
                ],
                description: 'Determines if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType" /> parameter.',
                returnsDescription: '<c>true</c> if the converter can convert the <paramref name="sourceValue"/> parameter to the <paramref name="destinationType" /> parameter, otherwise <c>false</c>.',
            }));
            converterClass.add(new codegen_csharp_1.LambdaMethod('ConvertFrom', codegen_csharp_1.dotnet.Object, new codegen_csharp_1.LiteralExpression(`${enumInfo.details.name}.CreateFrom(sourceValue)`), {
                override: codegen_csharp_1.Modifier.Override,
                parameters: [
                    new codegen_csharp_1.Parameter('sourceValue', codegen_csharp_1.dotnet.Object, { description: 'the <see cref="System.Object"/> to convert from' }),
                    new codegen_csharp_1.Parameter('destinationType', codegen_csharp_1.System.Type, { description: 'the <see cref="System.Type" /> to convert to' }),
                    new codegen_csharp_1.Parameter('formatProvider', codegen_csharp_1.System.IFormatProvider, { description: 'not used by this TypeConverter.' }),
                    new codegen_csharp_1.Parameter('ignoreCase', codegen_csharp_1.dotnet.Bool, { description: 'when set to <c>true</c>, will ignore the case when converting.' }),
                ],
                description: 'Converts the <paramref name="sourceValue" /> parameter to the <paramref name="destinationType" /> parameter using <paramref name="formatProvider" /> and <paramref name="ignoreCase" /> ',
                returnsDescription: `an instance of <see cref="${enumInfo.details.name}" />, or <c>null</c> if there is no suitable conversion.`
            }));
            converterClass.add(new codegen_csharp_1.LambdaMethod('ConvertTo', codegen_csharp_1.dotnet.Object, codegen_csharp_1.dotnet.Null, {
                override: codegen_csharp_1.Modifier.Override,
                parameters: [
                    new codegen_csharp_1.Parameter('sourceValue', codegen_csharp_1.dotnet.Object, { description: 'the <see cref="System.Object"/> to convert from' }),
                    new codegen_csharp_1.Parameter('destinationType', codegen_csharp_1.System.Type, { description: 'the <see cref="System.Type" /> to convert to' }),
                    new codegen_csharp_1.Parameter('formatProvider', codegen_csharp_1.System.IFormatProvider, { description: 'not used by this TypeConverter.' }),
                    new codegen_csharp_1.Parameter('ignoreCase', codegen_csharp_1.dotnet.Bool, { description: 'when set to <c>true</c>, will ignore the case when converting.' }),
                ], description: 'NotImplemented -- this will return <c>null</c>',
                returnsDescription: 'will always return <c>null</c>.'
            }));
            enumClass.add(new codegen_csharp_1.Attribute(powershell_declarations_1.TypeConverterAttribute, { parameters: [new codegen_csharp_1.LiteralExpression(`typeof(${converterClass})`)] }));
        }
    }
}
exports.EnumNamespace = EnumNamespace;
//# sourceMappingURL=namespace.js.map