package handlers import ( "errors" "fmt" "sync" "time" "git.coopgo.io/coopgo-platform/multimodal-routing/libs/carpool" "github.com/paulmach/orb" "github.com/paulmach/orb/geojson" "github.com/rs/zerolog/log" "github.com/spf13/viper" ) type CarpoolRoutingHandler struct { OperatorAPIs []carpool.CarpoolOperatorAPI } func NewCarpoolRoutingHandler(cfg *viper.Viper) (*CarpoolRoutingHandler, error) { operatorApis := []carpool.CarpoolOperatorAPI{} operators := cfg.Get("operators").([]any) for _, operator := range operators { o := operator.(map[string]any) operatorType, ok := o["type"].(string) if !ok { return nil, errors.New("missing operator type") } if operatorType == "blablacardaily" { operatorId, ok := o["operator_id"].(string) if !ok { return nil, errors.New("missing operator_id") } apiKey, ok := o["api_key"].(string) if !ok { return nil, errors.New("missing api_key") } baseUrl, ok := o["base_url"].(string) if !ok { return nil, errors.New("missing base_url") } operatorapi, err := carpool.NewBBCDailyCarpoolAPI(operatorId, apiKey, baseUrl) if err != nil { return nil, fmt.Errorf("could not create Blablacar Daily API: %w", err) } operatorApis = append(operatorApis, operatorapi) } } return &CarpoolRoutingHandler{ OperatorAPIs: operatorApis, }, nil } // TODO add options (WithTimeDelta, etc...) func (h CarpoolRoutingHandler) Search(results chan *geojson.FeatureCollection, departure geojson.Feature, destination geojson.Feature, departureDate time.Time) error { defer close(results) defaultTimeDelta := 3600 * time.Second defaultDepartureRadius := int64(10) defaultDestinationRadius := int64(10) defaultCount := int64(10) var wg2 sync.WaitGroup for _, api := range h.OperatorAPIs { wg2.Add(1) go func(results chan *geojson.FeatureCollection, wg2 *sync.WaitGroup) { defer wg2.Done() r, err := api.GetDriverJourneys(departure.Point().Lat(), departure.Point().Lon(), destination.Point().Lat(), destination.Point().Lon(), departureDate, &defaultTimeDelta, defaultDepartureRadius, defaultDestinationRadius, defaultCount) if err != nil { log.Error().Err(err).Str("operator", api.GetOperatorId()).Msg("error in carpool api request") return } for _, journey := range r { // Departure geo := geojson.NewFeatureCollection() dep := geojson.NewFeature(orb.Point{journey.PassengerPickupLng, journey.PassengerPickupLat}) dep.Properties["type"] = "departure" dep.Properties["label"] = journey.PassengerPickupAddress // TODO Polyline to GeoJSON LineString // Destination dest := geojson.NewFeature(orb.Point{journey.PassengerDropLng, journey.PassengerDropLat}) dest.Properties["type"] = "destination" dest.Properties["label"] = journey.PassengerDropAddress // Carpool GeoJSON definition geo.Features = append(geo.Features, dep) geo.Features = append(geo.Features, dest) geo.ExtraMembers = geojson.Properties{ "journey_type": "carpool", "ocss": journey, } results <- geo } }(results, &wg2) } wg2.Wait() return nil }