#include "testing/testing.hpp"

#include "routing/routing_callbacks.hpp"

#include "routing/routing_integration_tests/routing_test_tools.hpp"

#include "geometry/mercator.hpp"

namespace bicycle_route_test
{
using namespace integration;
using namespace routing;
using namespace routing::turns;

UNIT_TEST(RussiaMoscowSevTushinoParkPreferingBicycleWay)
{
  // Prefer a good quality dedicated cycleway over bad quality path + footway.
  /// @todo: replace with a better case that prefers a longer cycleway to e.g. shorter track of same quality.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.87445, 37.43711),
                                   {0., 0.}, mercator::FromLatLon(55.87203, 37.44274), 460.0);
}

UNIT_TEST(RussiaMoscowNahimovskyLongRoute)
{
  // Get onto a secondary and follow it. Same as GraphHopper.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.66151, 37.63320),
                                   {0., 0.}, mercator::FromLatLon(55.67695, 37.56220), 5670.0);
}

UNIT_TEST(Russia_UseSteps)
{
  // Use the steps as the detour is way too long.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(55.4403114, 37.7740223), {0., 0.},
                                   mercator::FromLatLon(55.439703, 37.7725059), 139.058);
}

UNIT_TEST(Italy_AvoidSteps)
{
  // 690m detour instead of taking a 120m shortcut via steps.
  // Same as Valhalla. But GraphHopper prefers steps.
  // https://github.com/organicmaps/organicmaps/issues/2253
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(42.4631, 14.21342),
                                   {0., 0.}, mercator::FromLatLon(42.46343, 14.2125), 687.788);
}

UNIT_TEST(SwedenStockholmCyclewayPriority)
{
  /// @todo(pastk): DELETE: the cycleway is the shortest and the only obvious option here anyway, what's the value of
  /// this test?
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(59.33151, 18.09347),
                                   {0., 0.}, mercator::FromLatLon(59.33052, 18.09391), 113.0);
}

UNIT_TEST(Poland_PreferCyclewayDetour)
{
  // Prefer a longer cycleway route with a little uphill
  // rather than a 130m shorter route via a residential.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(50.043813, 20.016456), {0., 0.},
                                   mercator::FromLatLon(50.047522, 20.029986), 1354.04);
}

UNIT_TEST(Poland_PreferCycleway_AvoidPrimary)
{
  // Prefer a 180m longer and a little uphill cycleway detour to avoid a straight primary road.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(50.031478, 19.948912), {0., 0.},
                                   mercator::FromLatLon(50.036289, 19.941198), 993.818);
}

UNIT_TEST(NetherlandsAmsterdamBicycleNo)
{
  // Snap start/finish point to the closest suitable road.
  // The closest road here has a bicycle=no tag so its ignored and the next closest cycleway is used.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(52.32716, 5.05932),
                                   {0., 0.}, mercator::FromLatLon(52.32587, 5.06121), 338.0);
}

UNIT_TEST(NetherlandsAmsterdamBicycleYes)
{
  // Test that a highway=unclassified gets a significant boost due to presence of bicycle=yes tag.
  /// @todo(pastk): it shouldn't as there is no cycling infra (cycleway:both=no
  /// https://www.openstreetmap.org/way/214196820) and bicycle=yes means "its legal", not "its fast", see
  /// https://github.com/organicmaps/organicmaps/issues/9593
  TRouteResult const routeResult =
      CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(52.32872, 5.07527), {0.0, 0.0},
                     mercator::FromLatLon(52.33853, 5.08941));

  TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
  TestRouteTime(*routeResult.first, 284.38);
}

UNIT_TEST(Netherlands_Amsterdam_OnewaySt_CyclewayOpposite)
{
  // Bicycles can go against the car traffic on oneway=yes roads if there is a cycleway=opposite tag.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(52.37571, 4.88591),
                                   {0., 0.}, mercator::FromLatLon(52.37736, 4.88744), 212.8);
}

UNIT_TEST(RussiaMoscowKashirskoe16ToCapLongRoute)
{
  // There is no dedicated bicycle infra, except short end part. All OSM routers give different results,
  // OM yields a short and logical route shortcutting via some service roads and footways (allowed in Russia).
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.66230, 37.63214),
                                   {0., 0.}, mercator::FromLatLon(55.68927, 37.70356), 6968.64);
}

UNIT_TEST(Germany_UseServiceCountrysideRoads)
{
  /// @todo(pastk): long service countryside roads is a mismapping probably.
  /// https://github.com/organicmaps/organicmaps/pull/9692#discussion_r1850558462
  // Goes by smaller roads, including service ones. Also avoids extra 60m uphill
  // of the secondary road route. Most similar to Valhalla, but 2km shorter.
  // https://github.com/organicmaps/organicmaps/issues/6027
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(49.1423, 10.068),
                                   {0., 0.}, mercator::FromLatLon(49.3023, 10.5738), 47769.2);
}

UNIT_TEST(RussiaMoscowServicePassThrough)
{
  // Passing through living_street and service is allowed in Russia.
  TRouteResult route = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
                                                   mercator::FromLatLon(55.79649, 37.53738), {0., 0.},
                                                   mercator::FromLatLon(55.79618, 37.54071));
  TEST_EQUAL(route.second, RouterResultCode::NoError, ());
}

UNIT_TEST(Russia_Moscow_UseAllowedFootways)
{
  // Shortcut via footways if its allowed in the country.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(55.6572884, 37.6142816), {0., 0.},
                                   mercator::FromLatLon(55.6576455, 37.6164412), 182.766);
}

UNIT_TEST(Spain_Barcelona_UsePedestrianAndLivingStreet)
{
  // Don't make long detours to avoid pedestrian and living streets.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(41.40080, 2.16026),
                                   {0.0, 0.0}, mercator::FromLatLon(41.39937, 2.15735),
                                   516.14 /* expectedRouteMeters */);
}

UNIT_TEST(Poland_UseLivingStreet)
{
  // Don't make a long detour via an uphill residential to avoid a living street.
  // https://github.com/organicmaps/organicmaps/pull/9692#discussion_r1851446320
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(50.006085, 19.962158), {0.0, 0.0},
                                   mercator::FromLatLon(50.006664, 19.957639), 335.978 /* expectedRouteMeters */);
}

UNIT_TEST(Poland_UseLivingStreet2)
{
  // Don't make a long detour via service and residential to avoid a living street.
  // (a more strict and longer test than above)
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(50.096027, 19.90433), {0.0, 0.0},
                                   mercator::FromLatLon(50.099875, 19.889867), 1124.7 /* expectedRouteMeters */);
}

UNIT_TEST(RussiaKerchStraitFerryRoute)
{
  // Use a cross-mwm ferry.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(45.4167, 36.7658),
                                   {0.0, 0.0}, mercator::FromLatLon(45.3653, 36.6161), 17151.4);
}

UNIT_TEST(SwedenStockholmBicyclePastFerry)
{
  // Several consecutive ferries.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(59.4725, 18.51355),
                                   {0.0, 0.0}, mercator::FromLatLon(59.42533, 18.35991), 14338.0);
}

UNIT_TEST(CrossMwmKaliningradRegionToLiepaja)
{
  // A cross mwm route (3 regions). Includes a ferry.
  integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Bicycle),
                                                mercator::FromLatLon(54.63519, 21.80749), {0., 0.},
                                                mercator::FromLatLon(56.51119, 21.01847), 266992);
}

UNIT_TEST(Lithuania_Avoid_Ferry_Long_Route)
{
  // Avoid ferry Dreverna-Juodkrantė-Klaipėda.
  RoutingOptionSetter optionsGuard(RoutingOptions::Ferry);

  // GraphHopper makes a detour (via unpaved), OSRM goes straight with highway=primary,
  // Valhalla uses a part of the primary. A user says that GraphHopper is the best option.
  // https://www.openstreetmap.org/directions?engine=graphhopper_bicycle&route=55.340%2C21.459%3B55.715%2C21.135
  // OM uses a much shorter (56km vs 64km) route with bicycle=yes tracks and a short path section.
  /// @todo(pastk): the route goes through a landuse=military briefly and OM doesn't account for that.
  /// And too much preference is given to bicycle=yes track, see https://github.com/organicmaps/organicmaps/issues/9593
  integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Bicycle),
                                                mercator::FromLatLon(55.3405073, 21.4595925), {0., 0.},
                                                mercator::FromLatLon(55.7140174, 21.1365445), 56243.2);
}

UNIT_TEST(SpainTenerife_AdejeVilaflor)
{
  // Google shows exactly this route while OSRM, GraphHopper and Valhalla gives much more longer
  // (path + bicycle instead of unclassified).

  // Test on riding up from Adeje (sea level) to Vilaflor (altitude 1400 meters).
  // A long ETA due to going uphill.
  TRouteResult const res =
      CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(28.11984, -16.72592), {0., 0.},
                     mercator::FromLatLon(28.15865, -16.63704));
  TEST_EQUAL(res.second, RouterResultCode::NoError, ());

  TestRouteLength(*res.first, 26918.5);
  TestRouteTime(*res.first, 10817);
}

UNIT_TEST(SpainTenerife_VilaflorAdeje)
{
  // Google shows exactly this route while OSRM, GraphHopper and Valhalla gives much more longer
  // (path + bicycle instead of unclassified).

  // Test on riding down from Vilaflor (altitude 1400 meters) to Adeje (sea level).
  // A short ETA going downhill.
  TRouteResult const res =
      CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(28.15865, -16.63704), {0., 0.},
                     mercator::FromLatLon(28.11984, -16.72592));
  TEST_EQUAL(res.second, RouterResultCode::NoError, ());

  TestRouteLength(*res.first, 25196.4);
  TestRouteTime(*res.first, 4586);
}

// Two tests on not building route against traffic on road with oneway:bicycle=yes.
UNIT_TEST(Munich_OnewayBicycle1)
{
  /// @todo Should combine TurnSlightLeft, TurnLeft, TurnLeft into UTurnLeft?
  integration::CalculateRouteAndTestRouteLength(
      integration::GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(48.1601673, 11.5630245), {0.0, 0.0},
      mercator::FromLatLon(48.1606349, 11.5631699), 264.042 /* expectedRouteMeters */);
}

UNIT_TEST(Munich_OnewayBicycle2)
{
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(48.17819, 11.57286),
                                   {0.0, 0.0}, mercator::FromLatLon(48.17867, 11.57303),
                                   201.532 /* expectedRouteMeters */);
}

UNIT_TEST(London_GreenwichTunnel)
{
  // Use the bicycle=dismount foot tunnel https://www.openstreetmap.org/way/4358990
  // as a detour is way too long.
  // https://github.com/organicmaps/organicmaps/issues/8028

  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(51.4817397, -0.0100070258), {0.0, 0.0},
                                   mercator::FromLatLon(51.4883739, -0.00809729298), 1183.12 /* expectedRouteMeters */);
}

UNIT_TEST(Batumi_AvoidServiceDetour)
{
  // Go straight via a residential without a short detour via service road.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(41.6380014, 41.6269446), {0.0, 0.0},
                                   mercator::FromLatLon(41.6392113, 41.6260084), 160.157 /* expectedRouteMeters */);
}

UNIT_TEST(Gdansk_AvoidLongCyclewayDetour)
{
  /// @todo(pastk): DELETE: the preferred route goes by a shared cycleway also - replace with a better case (the next
  /// one!)
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(54.2632738, 18.6771661), {0.0, 0.0},
                                   mercator::FromLatLon(54.2698882, 18.6765837), 760.749 /* expectedRouteMeters */);
}

UNIT_TEST(Netherlands_AvoidLongCyclewayDetour)
{
  // Same as GraphHopper.
  // The first sample from https://github.com/organicmaps/organicmaps/issues/1772
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(52.253405, 6.182288), {0.0, 0.0},
                                   mercator::FromLatLon(52.247599, 6.197973), 1440.8 /* expectedRouteMeters */);
}

UNIT_TEST(Poland_AvoidDetourAndExtraCrossings)
{
  /// @todo Better (closest) road crossing is ignored.
  // Avoid making a longer cycleway detour which involves extra road crossings.
  // Same as GraphHopper. Valhalla suggests going by the road (worse for cyclists
  // really preferring to avoid cars whenever possible, may be preferred
  // for more aggressive ones depending on light phase to go through one traffic light only).
  // https://github.com/organicmaps/organicmaps/issues/7954
  // https://github.com/organicmaps/organicmaps/pull/9692#discussion_r1849627559
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(50.08227, 20.03348),
                                   {0.0, 0.0}, mercator::FromLatLon(50.08253, 20.03191),
                                   157.7 /* expectedRouteMeters */);
}

UNIT_TEST(Germany_DontAvoidNocyclewayResidential)
{
  // No strange detours to avoid a nocycleway residential. Same as GraphHopper.
  // https://github.com/organicmaps/organicmaps/issues/4059#issuecomment-1399338757
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(51.33772, 12.41432),
                                   {0.0, 0.0}, mercator::FromLatLon(51.33837, 12.40958),
                                   359.495 /* expectedRouteMeters */);
}

UNIT_TEST(UK_UseNocyclewayTertiary)
{
  // A preferred route is through nocycleway tertiary roads. Same as all OSM routers.
  // The detour is via a shared cycleway and with 130m less alt gain, but is 4km longer.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(51.3826906, -2.3481788), {0.0, 0.0},
                                   mercator::FromLatLon(51.3615095, -2.3114138), 4468.83 /* expectedRouteMeters */);
}

UNIT_TEST(Germany_UseResidential)
{
  // No long detour to avoid a short residential.
  // https://github.com/organicmaps/organicmaps/issues/9330
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(48.1464472, 11.5589919), {0.0, 0.0},
                                   mercator::FromLatLon(48.1418297, 11.5602123), 591.427 /* expectedRouteMeters */);
}

UNIT_TEST(Belarus_StraightFootway)
{
  /// @todo OM changes lanes because of altitude?
  // Prefer footways over roads in Belarus due to local laws.
  // https://github.com/organicmaps/organicmaps/issues/4145
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(53.8670285, 30.3162749), {0.0, 0.0},
                                   mercator::FromLatLon(53.876436, 30.3348084), 1613.34 /* expectedRouteMeters */);
}

UNIT_TEST(Spain_Madrid_DedicatedCycleway)
{
  // Check that OM uses dedicated "Carril bici del Paseo de la Castellana".
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(40.459616, -3.690031), {0.0, 0.0},
                                   mercator::FromLatLon(40.4403523, -3.69267444), 2283.89 /* expectedRouteMeters */);
}

// https://github.com/organicmaps/organicmaps/issues/7047
UNIT_TEST(Seoul_ElevationDetour)
{
  // The longer 664m route has less uphill Ascent: 25 Descent: 17
  // The shorter 545m route has bigger Ascent: 37 Descent: 29n.
  // OM prefers a shorter one (like Graphhopper). Valhalla prefers the longer one.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(37.510519, 127.101251), {0.0, 0.0},
                                   mercator::FromLatLon(37.513874, 127.099234), 544.063 /* expectedRouteMeters */);
}

UNIT_TEST(Spain_Zaragoza_Fancy_NoBicycle_Crossings)
{
  // A highway=crossing node https://www.openstreetmap.org/node/258776322 on the way
  // has bicycle=no, which doesn't prevent routing along this road.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(41.6523561, -0.881151311), {0.0, 0.0},
                                   mercator::FromLatLon(41.6476614, -0.885694674), 649.855 /* expectedRouteMeters */);
}

UNIT_TEST(Germany_Use_Bicycle_Track)
{
  // Avoid primary and prefer smaller roads and tracks with bicycle=yes.
  /// @todo Still prefers a no-cycling-infra but bicycle=yes secondary rather than a paved track,
  /// see https://github.com/organicmaps/organicmaps/issues/1201#issuecomment-946042937
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(48.420723, 9.90350146), {0.0, 0.0},
                                   mercator::FromLatLon(48.4080367, 9.86597073), 3778.41 /* expectedRouteMeters */);
}

UNIT_TEST(Finland_Use_Tertiary_LowTraffic)
{
  // Detour via a tertiary to avoid a secondary.
  // https://github.com/orgs/organicmaps/discussions/5158#discussioncomment-5938807
  /// @todo(pastk): prefer roads with lower maxspeed.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(61.5445696, 23.9394003), {0.0, 0.0},
                                   mercator::FromLatLon(61.6153965, 23.876755), 9876.65 /* expectedRouteMeters */);
}

UNIT_TEST(Belarus_Stolbcy_Use_Unpaved)
{
  // Goes by a paved streets and an compacted track in the end.
  // Same as GraphHopper and Valhalla detours the unpaved paths.
  // OSRM shortcuts through paths and a ford.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(53.471389, 26.7422186), {0.0, 0.0},
                                   mercator::FromLatLon(53.454082, 26.7560061), 5233.27 /* expectedRouteMeters */);
}

UNIT_TEST(Russia_UseTrunk_Long)
{
  // Prefer riding via a straight trunk road instead of taking a long +30% detour via smaller roads.
  /// @todo(pastk): DELETE: This test is controversial as this route has sections with longer relative trunk-avoiding
  /// detours e.g. from 67.9651692,32.8685132 to 68.022093,32.9654391 its +40% longer via a teriary and its OK?
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(66.271, 33.048),
                                   {0.0, 0.0}, mercator::FromLatLon(68.95, 33.045), 404262 /* expectedRouteMeters */);
}

/// @todo(pastk): find a good "avoid trunk" test case where trunk allows cycling.
UNIT_TEST(Russia_UseTrunk)
{
  // Prefer riding via a straight trunk road instead of taking weird detours via smaller roads
  // (651m via a tertiaty + service in this case).
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(68.0192918, 32.9576269), {0.0, 0.0},
                                   mercator::FromLatLon(68.0212968, 32.9632167), 323.951 /* expectedRouteMeters */);
}

UNIT_TEST(Russia_UseTrunk_AvoidGasStationsDetours)
{
  /// @todo(pastk): still OM detours into many petrol stations along the trunk.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(55.9132468, 39.1453188), {0.0, 0.0},
                                   mercator::FromLatLon(55.9146268, 39.153307), 613.721 /* expectedRouteMeters */);
}

UNIT_TEST(Netherlands_IgnoreCycleBarrier_WithoutAccess)
{
  // There is a barrier=cycle_barrier in the beginning of the route
  // and it doesn't affect routing as there is no explicit bicycle=no.
  // https://github.com/organicmaps/organicmaps/issues/3920
  /// @todo(pastk): such barrier should have a small penalty in routing
  /// as it slows down a cyclist.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(51.9960994, 5.67350176), {0.0, 0.0},
                                   mercator::FromLatLon(51.9996861, 5.67299133), 428.801);
}

UNIT_TEST(UK_ForbidGates_WithoutAccess)
{
  // A barrier=gate without explicit access leads to a long detour.
  // https://www.openstreetmap.org/node/6993853766
  /// @todo OSRM/Valhalla/GraphHopper ignore such gates,
  /// see
  /// https://www.openstreetmap.org/directions?engine=fossgis_valhalla_bicycle&route=51.3579329%2C-2.3137701%3B51.3574666%2C-2.3152644
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(51.3579329, -2.3137701), {0.0, 0.0},
                                   mercator::FromLatLon(51.3574666, -2.31526436), 1149.28);
}

UNIT_TEST(UK_Canterbury_AvoidDismount)
{
  /// @todo(pastk): the case is controversial, a user emailed "All cyclists in our town use this particular footway"
  /// but we don't know if cyclists dismount there or just cycle through (ignoring the UK rules).
  // A shortcut via a footway is 305 meters, ETAs are similar, but cyclists prefer to ride!
  // Check the London_GreenwichTunnel case for when dismounting is reasonable as the detour is way too long.
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(51.2794435, 1.05627788), {0.0, 0.0},
                                   mercator::FromLatLon(51.2818863, 1.05725286), 976);
}

// https://github.com/organicmaps/organicmaps/issues/6355
UNIT_TEST(Austria_BidirLivingStreet)
{
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(48.2053411, 16.3524902), {0.0, 0.0},
                                   mercator::FromLatLon(48.2064399, 16.3528722), 304.53);
}

UNIT_TEST(Germany_BicycleYes_VehicleNo)
{
  CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
                                   mercator::FromLatLon(48.077322, 11.252503), {0.0, 0.0},
                                   mercator::FromLatLon(48.074355, 11.2472321), 551.705);
}

}  // namespace bicycle_route_test
