import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { readFileSync } from 'fs'; import * as yaml from 'js-yaml'; import { Model } from 'mongoose'; import { join } from 'path'; import { SemanticVersionDto } from 'src/versioning/dto/semanticversion.dto'; import { VersioningService } from '../versioning/versioning.service'; import { PerformanceDocument } from './models/performance.model'; const COMPONENT_NAME = 'performance'; @Injectable() export class PerformanceService { private static readPerformanceFile(): Record { return yaml.load( readFileSync(join(process.cwd(), 'config/performance.yaml'), 'utf8'), ) as Record; } private async updatePerformanceData( performanceData: Record, version: SemanticVersionDto, ): Promise { return this.performanceModel.deleteMany({}).then(async () => { const invalidEntries: string[] = []; for (const key in performanceData) { if (key !== 'FILEINFO') { const validAircraft = performanceData[key]['speedabovefl240'] !== undefined && performanceData[key]['rodabovefl240'] !== undefined && performanceData[key]['speedabovefl100'] !== undefined && performanceData[key]['rodabovefl100'] !== undefined && performanceData[key]['speedbelowfl100'] !== undefined && performanceData[key]['rodbelowfl100'] !== undefined && performanceData[key]['speedapproach'] !== undefined; if (!validAircraft) { invalidEntries.push(key); } else { await this.performanceModel.create({ icaoCode: key, aboveFL240: { speed: performanceData[key]['speedabovefl240'], rateOfDescend: performanceData[key]['rodabovefl240'], }, aboveFL100: { speed: performanceData[key]['speedabovefl100'], rateOfDescend: performanceData[key]['rodabovefl100'], }, belowFL100: { speed: performanceData[key]['speedbelowfl100'], rateOfDescend: performanceData[key]['rodbelowfl100'], }, minimalApproachSpeed: performanceData[key]['speedapproach'], }); } } } await this.versioningService.updateComponent( COMPONENT_NAME, performanceData['FILEINFO']['createdAt'], version, ); return invalidEntries; }); } private async validateAndUpdatePerformanceData(): Promise { // read the performance file and validate the version length const data = PerformanceService.readPerformanceFile(); const versionParts = (data['FILEINFO']['version'] as string).split('.'); if (versionParts.length !== 3) return []; // create the fileversion const fileversion: SemanticVersionDto = { main: parseInt(versionParts[0]), major: parseInt(versionParts[1]), minor: parseInt(versionParts[2]), }; return this.versioningService .findComponent(COMPONENT_NAME) .then((resp) => { if ( resp === null || VersioningService.newerVersion( { main: resp.versionMain, major: resp.versionMajor, minor: resp.versionMinor, }, fileversion, ) ) { return this.updatePerformanceData(data, fileversion); } return []; }) .catch(() => this.updatePerformanceData(data, fileversion)); } constructor( @InjectModel('performance') private readonly performanceModel: Model, private readonly versioningService: VersioningService, ) { this.validateAndUpdatePerformanceData(); } }