package service import ( "context" "encoding/csv" "fmt" "io" "log" "strings" "bugulma/backend/internal/domain" ) // ImportPublicTransportData imports stops and routes from the service's loaded files into repository func ImportPublicTransportData(ctx context.Context, svc *PublicTransportService, repo domain.PublicTransportRepository) error { if svc == nil || repo == nil { return nil // nothing to do } // Seed common stops from enriched JSON if available if cs := svc.ListStops(); len(cs) > 0 { for key, v := range cs { m, ok := v.(map[string]interface{}) if !ok { continue } stop := &domain.PublicTransportStop{ID: key} if name, ok := m["name"].(string); ok { stop.Name = name } if nameEn, ok := m["name_en"].(string); ok { stop.NameEn = nameEn } if typ, ok := m["type"].(string); ok { stop.Type = typ } if addr, ok := m["address"].(string); ok { stop.Address = addr } if osm, ok := m["osm_id"].(string); ok { stop.OsmID = osm } if est, ok := m["estimated"].(bool); ok { stop.Estimated = est } if loc, ok := m["location"].(map[string]interface{}); ok { if lat, ok := loc["lat"].(float64); ok { stop.Latitude = &lat } if lng, ok := loc["lng"].(float64); ok { stop.Longitude = &lng } } if routes, ok := m["routes_served"].([]interface{}); ok { for _, r := range routes { if s, ok := r.(string); ok { stop.RoutesServed = append(stop.RoutesServed, s) } } } if err := repo.UpsertStop(ctx, stop); err != nil { log.Printf("warning: failed to upsert stop %s: %v", stop.ID, err) } } } // Seed GTFS routes from routes.txt if routesCSV, err := svc.ReadGTFSFile("routes.txt"); err == nil { r := csv.NewReader(strings.NewReader(routesCSV)) // Read header header, err := r.Read() if err == nil { idx := map[string]int{} for i, h := range header { idx[h] = i } for { rec, err := r.Read() if err == io.EOF { break } if err != nil { return fmt.Errorf("failed to read routes CSV: %w", err) } id := rec[idx["route_id"]] rt := &domain.PublicTransportRoute{ID: id} if v, ok := idx["agency_id"]; ok { rt.AgencyID = rec[v] } if v, ok := idx["route_short_name"]; ok { rt.ShortName = rec[v] } if v, ok := idx["route_long_name"]; ok { rt.LongName = rec[v] } if v, ok := idx["route_type"]; ok { if rec[v] != "" { // parse int route_type // we keep it simple and ignore parse errors var rtType int fmt.Sscanf(rec[v], "%d", &rtType) rt.RouteType = rtType } } if err := repo.UpsertRoute(ctx, rt); err != nil { log.Printf("warning: failed to upsert route %s: %v", rt.ID, err) } } } } else { // Missing routes file is fine } return nil }