refactor: Update AFTN message parsing logic
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package parsers
|
||||
|
||||
import (
|
||||
"caatsm/internal/config"
|
||||
"caatsm/internal/domain"
|
||||
"caatsm/pkg/utils"
|
||||
"errors" // Import errors package to handle errors
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -12,6 +15,110 @@ const (
|
||||
BeginPartMarker = "BEGIN PART"
|
||||
)
|
||||
|
||||
type BodyParser struct {
|
||||
bodyPattern map[string]config.BodyConfig // Injected configuration for body patterns.
|
||||
}
|
||||
|
||||
func DefaultBodyParser() *BodyParser {
|
||||
return &BodyParser{bodyPattern: config.GetBodyPatterns()}
|
||||
}
|
||||
|
||||
func (bp *BodyParser) GetBodyPatterns() map[string]config.BodyConfig {
|
||||
return bp.bodyPattern
|
||||
}
|
||||
|
||||
func (bp *BodyParser) SetBodyPatterns(patterns map[string]config.BodyConfig) {
|
||||
bp.bodyPattern = patterns
|
||||
}
|
||||
|
||||
func (bp *BodyParser) Parse(body string) (interface{}, error) {
|
||||
log := utils.Logger
|
||||
data := make(map[string]string)
|
||||
for _, pattern := range bp.GetBodyPatterns() {
|
||||
for i, p := range pattern.Patterns {
|
||||
log.Debugf("Trying pattern %d: %s\n %s\n", i, p.Comments, p.Pattern)
|
||||
re := p.Expression
|
||||
match := re.FindStringSubmatch(body)
|
||||
if match != nil {
|
||||
log.Debugf("Matched : %v \n", match)
|
||||
for i, name := range re.SubexpNames() {
|
||||
if i != 0 && name != "" {
|
||||
data[name] = match[i]
|
||||
}
|
||||
}
|
||||
return CreateBodyData(data)
|
||||
}
|
||||
log.Debugf("No match for pattern %d\n", i)
|
||||
}
|
||||
}
|
||||
log.Errorf("No matching pattern found for body: %s", body)
|
||||
return data, errors.New("no matching pattern found for body")
|
||||
}
|
||||
|
||||
func CreateBodyData(data map[string]string) (interface{}, error) {
|
||||
switch data["type"] {
|
||||
case "ARR":
|
||||
return &domain.ARR{
|
||||
Category: data["type"],
|
||||
AircraftID: data["number"],
|
||||
SSRModeAndCode: data["ssr"],
|
||||
DepartureAirport: data["departure"],
|
||||
ArrivalAirport: data["arrival"],
|
||||
}, nil
|
||||
case "DEP":
|
||||
return &domain.DEP{
|
||||
Category: data["type"],
|
||||
AircraftID: data["number"],
|
||||
SSRModeAndCode: data["ssr"],
|
||||
DepartureAirport: data["departure"],
|
||||
DepartureTime: data["departure_time"],
|
||||
Destination: data["arrival"],
|
||||
}, nil
|
||||
case "FPL":
|
||||
return &domain.FPL{
|
||||
Category: data["type"],
|
||||
FlightNumber: data["number"],
|
||||
ReferenceData: data["reference_data"],
|
||||
AircraftID: data["aircraft"],
|
||||
SSRModeAndCode: data["surve"],
|
||||
FlightRulesAndType: data["indicator"],
|
||||
CruisingSpeedAndLevel: data["speed"] + data["level"],
|
||||
DepartureAirport: data["departure"],
|
||||
DepartureTime: data["departure_time"],
|
||||
Route: data["route"],
|
||||
DestinationAndTotalTime: data["destination"] + data["estt"],
|
||||
AlternateAirport: data["alter"],
|
||||
OtherInfo: fmt.Sprintf("%s %s REG/%s EET/%s SEL/%s PER/%s RIF/%s",
|
||||
data["pbn"], data["nav"], data["reg"], data["eet"], data["sel"], data["performance"], data["rif"]),
|
||||
SupplementaryInfo: "RMK/" + data["remark"],
|
||||
EstimatedArrivalTime: data["estimated_arrival_time"],
|
||||
PBN: data["pbn"],
|
||||
NavigationEquipment: data["nav"],
|
||||
EstimatedElapsedTime: data["eet"],
|
||||
SELCALCode: data["sel"],
|
||||
PerformanceCategory: data["performance"],
|
||||
RerouteInformation: data["rif"],
|
||||
Remarks: data["remark"],
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid message type: %s", data["type"])
|
||||
}
|
||||
}
|
||||
|
||||
func Parse(rawText string) (*domain.ParsedMessage, error) {
|
||||
message, err := ParseHeader(rawText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyParser := DefaultBodyParser()
|
||||
bodyData, err := bodyParser.Parse(message.BodyAndFooter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
message.BodyData = bodyData
|
||||
return &message, nil
|
||||
}
|
||||
|
||||
// ParseHeader parses the header of the message and returns a ParsedMessage struct
|
||||
func ParseHeader(fullMessage string) (domain.ParsedMessage, error) {
|
||||
fullMessage = strings.TrimSpace(fullMessage) // Trim leading and trailing spaces
|
||||
|
||||
Reference in New Issue
Block a user