"use strict";
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.generate = void 0;
const linq_1 = require("@azure-tools/linq");
const path_1 = require("path");
const project_1 = require("../sdk/project");
const ejs = require('ejs');
const resources = `${__dirname}/../../resources`;
async function generateModels(project) {
    const path = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'model.ejs');
    for (const model of (0, linq_1.values)(project.model.schemas.objects)) {
        if (model.extensions && (model.extensions['x-ms-client-flatten'] || model.extensions['x-ms-external']) || model.language.default.pagable) {
            // skip flattened model and pageble model
            continue;
        }
        const content = await ejs.renderFile(path, { model: model, project: project });
        project.state.writeFile(`${project.baseFolder}\\Models\\${model.language.default.name}.cs`, content, undefined, 'source-file-csharp');
    }
}
async function generateEnums(project) {
    const path = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'enum.ejs');
    for (const model of (0, linq_1.values)(project.model.schemas.sealedChoices)) {
        const content = await ejs.renderFile(path, { model: model, project: project });
        project.state.writeFile(`${project.baseFolder}\\Models\\${model.language.default.name}.cs`, content, undefined, 'source-file-csharp');
    }
}
async function generateMethodGroups(project) {
    const path = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'azureMethodGroup.ejs');
    const interfacePath = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'methodGroupInterface.ejs');
    const extensionPath = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'extensions.ejs');
    for (const operationGroup of (0, linq_1.values)(project.state.model.operationGroups)) {
        if (operationGroup.$key === '') {
            // for operations with no operation group, they will be added in the client class directly.
            const clientExtensionContent = await ejs.renderFile(extensionPath, { methodGroup: operationGroup, project: project, clientName: project.state.model.info.title });
            project.state.writeFile(`${project.baseFolder}\\${project.state.model.info.title}Extensions.cs`, clientExtensionContent, undefined, 'source-file-csharp');
            continue;
        }
        // generate method group class
        const key = project.helper.ConvertToValidMethodGroupKey(operationGroup.$key);
        const content = await ejs.renderFile(path, { methodGroup: operationGroup, project: project });
        project.state.writeFile(`${project.baseFolder}\\${key}Operations.cs`, content, undefined, 'source-file-csharp');
        // generate method group interface
        const interfaceContent = await ejs.renderFile(interfacePath, { methodGroup: operationGroup, project: project });
        project.state.writeFile(`${project.baseFolder}\\I${key}Operations.cs`, interfaceContent, undefined, 'source-file-csharp');
        // generate method group extensions
        const extensionContent = await ejs.renderFile(extensionPath, { methodGroup: operationGroup, project: project, clientName: '' });
        project.state.writeFile(`${project.baseFolder}\\${key}OperationsExtensions.cs`, extensionContent, undefined, 'source-file-csharp');
    }
}
async function generateClient(project) {
    const path = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'azureServiceClient.ejs');
    const content = await ejs.renderFile(path, { project: project });
    project.state.writeFile(`${project.baseFolder}\\${project.state.model.info.title}.cs`, content, undefined, 'source-file-csharp');
}
async function generateClientInterface(project) {
    const path = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'serviceClientInterface.ejs');
    const content = await ejs.renderFile(path, { project: project });
    project.state.writeFile(`${project.baseFolder}\\I${project.state.model.info.title}.cs`, content, undefined, 'source-file-csharp');
}
async function generatePageClasses(project) {
    for (const [key, value] of Object.entries(project.state.model.language.default.pageClasses)) {
        const path = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'page.ejs');
        const className = value;
        const nextLinkName = key.split(' ')[0];
        const itemName = key.split(' ')[1];
        const page = { className: className, nextLinkName: nextLinkName, itemName: itemName };
        const content = await ejs.renderFile(path, { project: project, page: page });
        project.state.writeFile(`${project.baseFolder}\\Models\\${page.className}.cs`, content, undefined, 'source-file-csharp');
    }
}
async function generateExceptions(project) {
    const processedException = new Set();
    const path = (0, path_1.join)((0, path_1.join)(resources, 'templates'), 'exception.ejs');
    for (const operationGroup of (0, linq_1.values)(project.state.model.operationGroups)) {
        for (const operation of (0, linq_1.values)(operationGroup.operations)) {
            if (operation.exceptions && operation.exceptions[0].schema) {
                const exception = operation.exceptions[0];
                if (processedException.has(exception.schema) || (exception.schema.extensions && exception.schema.extensions['x-ms-external'])) {
                    continue;
                }
                else {
                    processedException.add(exception.schema);
                }
                const content = await ejs.renderFile(path, { project: project, exception: exception });
                project.state.writeFile(`${project.baseFolder}\\Models\\${exception.schema.language.default.name}Exception.cs`, content, undefined, 'source-file-csharp');
            }
        }
    }
}
async function generate(service) {
    try {
        const project = await new project_1.Project(service).init();
        await generateClient(project);
        await generateClientInterface(project);
        await generateMethodGroups(project);
        await generateModels(project);
        await generateEnums(project);
        await generatePageClasses(project);
        await generateExceptions(project);
    }
    catch (E) {
        console.error(`${__filename} - FAILURE  ${JSON.stringify(E)}`);
        throw E;
    }
}
exports.generate = generate;
//# sourceMappingURL=sdk-generate.js.map