package cif import ( "strconv" "git.fjla.uk/owlboard/go-types/pkg/database" "git.fjla.uk/owlboard/go-types/pkg/upstreamApi" "git.fjla.uk/owlboard/timetable-mgr/helpers" "git.fjla.uk/owlboard/timetable-mgr/log" "go.uber.org/zap" ) func ConvertServiceType(input *upstreamApi.JsonScheduleV1, vstp bool) (*database.Service, error) { output := database.Service{ //TransactionType: input.TransactionType, StpIndicator: input.CifStpIndicator, Operator: input.AtocCode, TrainUid: input.CifTrainUid, Headcode: input.ScheduleSegment.SignallingId, PowerType: input.ScheduleSegment.CifPowerType, PlanSpeed: parseSpeed(&input.ScheduleSegment.CifSpeed), ScheduleStartDate: ParseCifDate(&input.ScheduleStartDate, "start"), ScheduleEndDate: ParseCifDate(&input.ScheduleEndDate, "end"), ServiceDetail: generateServiceDetail(&input.ScheduleSegment.CifTrainClass, &input.ScheduleSegment.SignallingId, &input.ScheduleSegment.CifCateringCode, &input.ScheduleSegment.CifSleepers, vstp), DaysRun: parseDaysRun(&input.ScheduleDaysRun), Stops: parseStops(&input.ScheduleSegment.ScheduleLocation), } return &output, nil } // Converts CifSpeed input string to an int32, automatically corrects VSTP speeds which are not actual speed values func parseSpeed(CIFSpeed *string) int32 { if CIFSpeed == nil { return 0 } if *CIFSpeed == "" { return int32(0) } actualSpeed, exists := helpers.SpeedMap[*CIFSpeed] if !exists { actualSpeed = *CIFSpeed } speed, err := strconv.ParseInt(actualSpeed, 10, 32) if err != nil { log.Warn("Unable to parse speed", zap.String("input-value", *CIFSpeed)) return int32(0) } return int32(speed) } // Not tested func parseStops(input *[]upstreamApi.CifScheduleLocation) []database.Stop { output := make([]database.Stop, 0, len(*input)) for _, item := range *input { stop := database.Stop{ PublicDeparture: item.PublicDeparture, PublicArrival: item.PublicArrival, WttDeparture: item.Departure, WttArrival: item.Arrival, Pass: item.Pass, Platform: item.Platform, ArrLine: item.Path, DepLine: item.Line, Tiploc: item.TiplocCode, IsPublic: isPublic(&item), } output = append(output, stop) } return output } // Ascertains whether a given location is a public stop or not func isPublic(input *upstreamApi.CifScheduleLocation) bool { if input.PublicArrival == "" && input.PublicDeparture == "" { return false } return true } // Generates a ServiceDetail struct based on the input func generateServiceDetail( cifTrainClass, signallingId, cateringCode, sleepers *string, vstp bool, ) database.ServiceDetail { return database.ServiceDetail{ FirstClass: hasFirstClass(cifTrainClass, signallingId), Catering: hasCatering(cateringCode), Sleeper: hasSleeper(sleepers), Vstp: vstp, } } // Ascertains whether the service offers first class func hasFirstClass(input, signallingId *string) bool { if input == nil || signallingId == nil { return false } // Handle non passenger headcodes and ensure first class is not shown as available firstChar := (*signallingId)[0] if firstChar == '3' || firstChar == '4' || firstChar == '5' || firstChar == '6' || firstChar == '7' || firstChar == '8' || firstChar == '0' { return false } return *input != "S" } // Ascertains whether the service offers catering func hasCatering(input *string) bool { if input == nil { return false } return *input != "" } // Ascertains whether the service offers sleeping berths func hasSleeper(input *string) bool { if input == nil { return false } return *input != "" }