"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.generator = exports.generatorId = void 0;
const node_path_1 = require("node:path");
const Generator = __importStar(require("@postxl/generator"));
const backend_actions_1 = require("../backend-actions");
const backend_core_1 = require("../backend-core");
const backend_repositories_1 = require("../backend-repositories");
const backend_update_1 = require("../backend-update");
const base_1 = require("../base");
const decoders_1 = require("../decoders");
const types_1 = require("../types");
const convert_functions_generator_1 = require("./generators/convert-functions.generator");
const detect_delta_all_models_generator_1 = require("./generators/detect-delta/detect-delta-all-models.generator");
const detect_delta_functions_generator_1 = require("./generators/detect-delta/detect-delta-functions.generator");
const model_function_generator_1 = require("./generators/detect-delta/model-function.generator");
const types_generator_1 = require("./generators/detect-delta/types.generator");
const import_module_generator_1 = require("./generators/import-module.generator");
const import_service_generator_1 = require("./generators/import-service.generator");
exports.generatorId = Generator.toGeneratorInterfaceId('backend-import');
exports.generator = {
    id: exports.generatorId,
    requires: [
        types_1.typesGeneratorId,
        backend_core_1.backendGeneratorId,
        base_1.baseGeneratorId,
        types_1.typesGeneratorId,
        backend_actions_1.backendActionsGeneratorId,
        backend_repositories_1.backendRepositoriesGeneratorId,
        decoders_1.decodersGeneratorId,
        backend_update_1.backendUpdateGeneratorId,
    ],
    register: (context) => {
        const module = {
            name: Generator.toClassName('ImportModule'),
            location: Generator.toBackendModuleLocation(`@import/import.module`),
        };
        const importModule = {
            name: Generator.toBackendModuleName('import'),
            moduleClass: module,
        };
        context.backend.modules.push(importModule);
        const convertFunctionLocation = Generator.toBackendModuleLocation(`@import/convert-import.functions`);
        const serviceLocation = Generator.toBackendModuleLocation(`@import/import.service`);
        const allModelsLocation = Generator.toBackendModuleLocation(`@import/detect-delta/models.detect-delta`);
        const typeLocation = Generator.toBackendModuleLocation(`@import/detect-delta/types`);
        const utilsLocation = Generator.toBackendModuleLocation(`@import/detect-delta/utils`);
        const actionScope = (0, backend_actions_1.toScopeName)('import');
        const importContext = {
            module: importModule,
            service: {
                name: Generator.toClassName('ImportService'),
                location: serviceLocation,
                variableName: Generator.toVariableName(`importService`),
            },
            actionScope,
            scopes: new Set([actionScope]),
            actions: {
                summary: {
                    action: { name: Generator.toTypeName(`Action_Import`), location: serviceLocation },
                    result: { name: Generator.toTypeName(`ActionResult_Import`), location: serviceLocation },
                },
                excel: {
                    action: { name: Generator.toTypeName(`Action_Import_Excel`), location: serviceLocation },
                    result: { name: Generator.toTypeName(`ActionResult_Import_Excel`), location: serviceLocation },
                },
                excelSeed: {
                    action: { name: Generator.toTypeName(`Action_Import_ExcelSeed`), location: serviceLocation },
                    result: { name: Generator.toTypeName(`ActionResult_Import_ExcelSeed`), location: serviceLocation },
                },
                data: {
                    action: { name: Generator.toTypeName(`Action_Import_Data`), location: serviceLocation },
                    result: { name: Generator.toTypeName(`ActionResult_Import_Data`), location: serviceLocation },
                },
                dataSeed: {
                    action: { name: Generator.toTypeName(`Action_Import_DataSeed`), location: serviceLocation },
                    result: { name: Generator.toTypeName(`ActionResult_Import_DataSeed`), location: serviceLocation },
                },
            },
            detectDelta: {
                allModels: {
                    name: Generator.toFunctionName(`detectDelta`),
                    location: allModelsLocation,
                    type: {
                        name: Generator.toTypeName(`Delta`),
                        location: allModelsLocation,
                    },
                    idMapType: {
                        name: Generator.toTypeName(`IdMap`),
                        location: allModelsLocation,
                    },
                    extractErrors: {
                        name: Generator.toFunctionName(`extractErrors`),
                        location: allModelsLocation,
                    },
                    summarizeErrors: {
                        name: Generator.toFunctionName(`summarizeErrors`),
                        location: allModelsLocation,
                    },
                },
                _utils: {
                    detectModelDelta: { name: Generator.toFunctionName(`detectModelDelta`), location: utilsLocation },
                    validation: {
                        params: { name: Generator.toTypeName(`ValidationFunctions`), location: utilsLocation },
                        referenceField: { name: Generator.toFunctionName(`validateReferenceField`), location: utilsLocation },
                        requiredFields: { name: Generator.toFunctionName(`validateRequiredFields`), location: utilsLocation },
                        requiredDependency: {
                            name: Generator.toFunctionName(`validateRequiredDependency`),
                            location: utilsLocation,
                        },
                        uniqueField: { name: Generator.toFunctionName(`validateUniqueField`), location: utilsLocation },
                        int: { name: Generator.toFunctionName(`validateInt`), location: utilsLocation },
                    },
                    getDelta: { name: Generator.toFunctionName(`getDelta`), location: utilsLocation },
                    keepErrors: { name: Generator.toFunctionName(`keepErrors`), location: utilsLocation },
                },
                types: {
                    generic: {
                        modelType: { name: Generator.toTypeName(`Delta_Model`), location: typeLocation },
                        create: {
                            type: { name: Generator.toTypeName(`Delta_Model_Create`), location: typeLocation },
                            discriminant: Generator.toDiscriminantValue(`create`),
                            typeGuard: { name: Generator.toFunctionName(`isDelta_Model_Create`), location: typeLocation },
                        },
                        update: {
                            type: { name: Generator.toTypeName(`Delta_Model_Update`), location: typeLocation },
                            discriminant: Generator.toDiscriminantValue(`update`),
                            typeGuard: { name: Generator.toFunctionName(`isDelta_Model_Update`), location: typeLocation },
                        },
                        delete: {
                            type: { name: Generator.toTypeName(`Delta_Model_Delete`), location: typeLocation },
                            discriminant: Generator.toDiscriminantValue(`delete`),
                            typeGuard: { name: Generator.toFunctionName(`isDelta_Model_Delete`), location: typeLocation },
                        },
                        unchanged: {
                            type: { name: Generator.toTypeName(`Delta_Model_Unchanged`), location: typeLocation },
                            discriminant: Generator.toDiscriminantValue(`unchanged`),
                            typeGuard: { name: Generator.toFunctionName(`isDelta_Model_Unchanged`), location: typeLocation },
                        },
                        errors: {
                            type: { name: Generator.toTypeName(`Delta_Model_Errors`), location: typeLocation },
                            discriminant: Generator.toDiscriminantValue(`errors`),
                            typeGuard: { name: Generator.toFunctionName(`isDelta_Model_Errors`), location: typeLocation },
                            missingField: {
                                type: { name: Generator.toTypeName(`Delta_Model_Errors_MissingField`), location: typeLocation },
                                discriminant: Generator.toDiscriminantValue(`required-field-missing`),
                            },
                            invalidReference: {
                                type: { name: Generator.toTypeName(`Delta_Model_Errors_InvalidReference`), location: typeLocation },
                                discriminant: Generator.toDiscriminantValue(`invalid-reference`),
                            },
                            nonUnique: {
                                type: { name: Generator.toTypeName(`Delta_Model_Errors_NonUnique`), location: typeLocation },
                                discriminant: Generator.toDiscriminantValue(`non-unique`),
                            },
                            invalidType: {
                                type: { name: Generator.toTypeName(`Delta_Model_Errors_InvalidType`), location: typeLocation },
                                discriminant: Generator.toDiscriminantValue(`invalid-type`),
                            },
                            isRequiredDependency: {
                                type: { name: Generator.toTypeName(`Delta_Model_Errors_IsRequiredDependency`), location: typeLocation },
                                discriminant: Generator.toDiscriminantValue(`is-required-dependency`),
                            },
                        },
                        delta_Fields: { name: Generator.toTypeName(`Delta_Fields`), location: typeLocation },
                    },
                },
            },
            converterFunctions: {
                importedDataToBulkMutations: {
                    location: convertFunctionLocation,
                    name: Generator.toFunctionName(`importedDataToBulkMutations`),
                },
                deltaToBulkMutations: {
                    location: convertFunctionLocation,
                    name: Generator.toFunctionName(`deltaToBulkMutations`),
                },
            },
        };
        context.actions.providers.push(importContext);
        const models = new Map();
        for (const [modelName, model] of context.models) {
            const modelWithImport = registerModelImport(model);
            models.set(modelName, modelWithImport);
        }
        return { ...context, import: importContext, models };
    },
    generate: async (context) => {
        const srcVfs = new Generator.VirtualFileSystem();
        srcVfs.write(Generator.toLocalFile(context.import.detectDelta.types.generic.modelType), (0, types_generator_1.generateDetectDeltaTypes)(context));
        srcVfs.write(Generator.toLocalFile(context.import.detectDelta._utils.detectModelDelta), (0, detect_delta_functions_generator_1.generateDetectDeltaFunctions)(context));
        srcVfs.write(Generator.toLocalFile(context.import.detectDelta.allModels), (0, detect_delta_all_models_generator_1.generateDetectDeltaAllModels)(context));
        srcVfs.write(Generator.toLocalFile(context.import.service), (0, import_service_generator_1.generateImportService)(context));
        srcVfs.write(Generator.toLocalFile(context.import.converterFunctions.deltaToBulkMutations), (0, convert_functions_generator_1.generateConvertImportFunctions)(context));
        for (const model of context.models.values()) {
            srcVfs.write(Generator.toLocalFile(model.import.delta.detect), (0, model_function_generator_1.generateDetectModelDeltaFunction)(context, model));
        }
        srcVfs.write(Generator.toLocalFile(context.import.module.moduleClass), (0, import_module_generator_1.generateImportModule)(context)); // NOSONAR - type assertion is required here
        const vfs = new Generator.VirtualFileSystem();
        vfs.insertFromVfs({ targetPath: 'src', vfs: srcVfs });
        vfs.write('/tsconfig.lib.json', Generator.generateTsConfig('import'));
        await vfs.loadFolder({ diskPath: (0, node_path_1.resolve)(__dirname, './template') });
        context.vfs.insertFromVfs({ targetPath: 'backend/libs/import', vfs: vfs });
        return context;
    },
};
function registerModelImport(model) {
    const value = {
        delta: {
            errors: {
                name: Generator.toTypeName(`Delta_Model_${model._conjugated.PascalCase}_Errors`),
                location: Generator.toBackendModuleLocation(`@import/detect-delta/${model._conjugated.camelCase}.detect-delta`),
            },
            detect: {
                name: Generator.toFunctionName(`detect${model._conjugated.PascalCase}Delta`),
                location: Generator.toBackendModuleLocation(`@import/detect-delta/${model._conjugated.camelCase}.detect-delta`),
            },
        },
    };
    return { ...model, import: value };
}
//# sourceMappingURL=import.generator.js.map