Files
aman-backend/src/inbound/inbound.controller.ts
2022-10-23 23:54:11 +02:00

242 lines
7.1 KiB
TypeScript

import {
Controller,
Get,
Delete,
Post,
Query,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { ApiBody, ApiQuery, ApiResponse } from '@nestjs/swagger';
import { AirportService } from '../airport/airport.service';
import { CoordinateConverter, WaypointConverter } from '../generic/converters';
import { CoordinateDto } from '../generic/dto/coordinate.dto';
import { WaypointDto } from '../generic/dto/waypoint.dto';
import { AircraftDto } from './dto/aircraft.dto';
import { ControllerInputDto } from './dto/controllerinput.dto';
import { FlightStateDto } from './dto/flightstate.dto';
import { InboundDto } from './dto/inbound.dto';
import { PlanningDto } from './dto/planning.dto';
import { PredictedWaypointDto } from './dto/predictedwaypoint.dto';
import { InboundService } from './inbound.service';
import { Aircraft } from './models/aircraft.model';
import { ControllerInput } from './models/controllerinput.model';
import { FlightState } from './models/flightstate.model';
import { Inbound } from './models/inbound.model';
import { Planning } from './models/planning.model';
import { PredictedWaypoint } from './models/predictedwaypoint.model';
@Controller('inbound')
export class InboundController {
constructor(
private readonly inboundService: InboundService,
private readonly airportService: AirportService,
) {}
private static convertAircraft<T>(aircraft: Aircraft | AircraftDto): T {
return {
type: aircraft.type,
wtc: aircraft.wtc,
wakeRecat: aircraft.wakeRecat,
engineCount: aircraft.engineCount,
engineType: aircraft.engineType,
} as T;
}
private static waypointsDtoToPredictedWaypoints(
waypoints: WaypointDto[],
): PredictedWaypoint[] {
const retval: PredictedWaypoint[] = [];
waypoints.forEach((waypoint) =>
retval.push({
waypoint: WaypointConverter.convert(waypoint),
altitude: undefined,
indicatedAirspeed: undefined,
groundspeed: undefined,
plannedOverheadTime: undefined,
}),
);
return retval;
}
private static convertControllerInput<T>(
input: ControllerInput | ControllerInputDto,
): T {
if (input instanceof ControllerInputDto) {
return {
reportedTime: input.reportedTime,
remainingRoute: InboundController.waypointsDtoToPredictedWaypoints(
input.remainingRoute,
),
requestedRunway: input.requestedRunway,
plannedStand: input.plannedStand,
} as T;
} else {
return {
reportedTime: input.reportedTime,
remainingRoute: InboundController.convertPredictedWaypoints(
input.remainingRoute,
),
requestedRunway: input.requestedRunway,
plannedStand: input.plannedStand,
} as T;
}
}
private static convertFlightState<T>(input: FlightState | FlightStateDto): T {
return {
position: CoordinateConverter.convert(input.position),
groundSpeed: input.groundSpeed,
groundTrack: input.groundTrack,
altitude: input.altitude,
verticalSpeed: input.verticalSpeed,
} as T;
}
private static convertPredictedWaypoints(
waypoints: PredictedWaypoint[],
): PredictedWaypointDto[] {
const retval: PredictedWaypointDto[] = [];
waypoints.forEach((input) =>
retval.push({
waypoint: WaypointConverter.convert<WaypointDto, CoordinateDto>(
input.waypoint,
),
altitude: input.altitude,
indicatedAirspeed: input.indicatedAirspeed,
groundspeed: input.groundspeed,
plannedOverheadTime: input.plannedOverheadTime,
}),
);
return retval;
}
private static convertPlanning(plan: Planning): PlanningDto {
if (plan === undefined) return undefined;
return {
arrivalRoute: plan.arrivalRoute,
arrivalRunway: plan.arrivalRunway,
plannedRoute: InboundController.convertPredictedWaypoints(
plan.plannedRoute,
),
fixedPlan: plan.fixedPlan,
};
}
private static convertInboundToInboundDto(inbound: Inbound): InboundDto {
return {
callsign: inbound.callsign,
destination: inbound.destination,
reporter: inbound.reporter,
aircraft: InboundController.convertAircraft(inbound.aircraft),
flightState: InboundController.convertFlightState(inbound.flightState),
controllerData: InboundController.convertControllerInput(
inbound.controllerData,
),
plan: InboundController.convertPlanning(inbound.plan),
};
}
private static convertInboundDtoInbound(inbound: InboundDto): Inbound {
return {
callsign: inbound.callsign,
destination: inbound.destination,
reporter: inbound.reporter,
aircraft: InboundController.convertAircraft(inbound.aircraft),
flightState: InboundController.convertFlightState(inbound.flightState),
controllerData: InboundController.convertControllerInput(
inbound.controllerData,
),
plan: undefined,
};
}
@Get('/inbounds')
@ApiQuery({
name: 'icao',
description: 'The ICAO code of the airport',
type: String,
})
@ApiResponse({
status: 200,
description: 'All known inbounds',
type: [InboundDto],
})
async inbounds(@Query('icao') icao: string): Promise<InboundDto[]> {
return this.inboundService.airportInbounds(icao).then((inbounds) => {
if (!inbounds) {
throw new HttpException(
'No inbounds for the airport found',
HttpStatus.NOT_FOUND,
);
}
const retval: InboundDto[] = [];
inbounds.forEach((inbound) =>
retval.push(InboundController.convertInboundToInboundDto(inbound)),
);
return retval;
});
}
@Post('/insert')
@ApiBody({
description: 'The new or updated inbound',
type: InboundDto,
})
@ApiResponse({
status: 201,
description: 'Inserted or updated the inbound',
})
@ApiResponse({
status: 404,
description: 'The destination airport is unknown',
})
async insert(inbound: InboundDto): Promise<boolean> {
return this.airportService.airport(inbound.destination).then((airport) => {
if (!airport) {
throw new HttpException('Airport not found', HttpStatus.NOT_FOUND);
}
return this.inboundService
.callsignKnown(inbound.callsign)
.then((known) => {
const internalInbound =
InboundController.convertInboundDtoInbound(inbound);
if (known) {
return this.inboundService.update(internalInbound);
} else {
return this.inboundService.add(internalInbound);
}
});
});
}
@Delete('/remove')
@ApiQuery({
name: 'callsign',
description: 'The callsign of the inbound',
type: String,
})
@ApiResponse({
status: 200,
description: 'The inbound is deleted',
})
@ApiResponse({
status: 404,
description: 'The inbound is unknown',
})
async remove(@Query('callsign') callsign: string): Promise<void> {
await this.inboundService.callsignKnown(callsign).then(async (known) => {
if (!known) {
throw new HttpException('Inbound not found', HttpStatus.NOT_FOUND);
}
await this.inboundService.remove(callsign);
});
}
}