-- enduro.lua — OSRM профиль для эндуро-роутинга "Дикий путь"
-- Логика: weight = distance / forward_rate
-- Чтобы грунтовки были ДЕШЕВЛЕ асфальта → у грунтовок forward_rate БОЛЬШЕ
-- (высокий rate → маленький weight на тот же distance)
-- У асфальта forward_rate МЕНЬШЕ → большой weight → OSRM избегает
-- Обновлён: 2026-05-15 (ET-001: блокировка шлагбаумов через mode.inaccessible,
--                       исключение footway/pedestrian/steps/corridor из графа)

api_version = 4

-- forward_rate: чем ВЫШЕ — тем ПРЕДПОЧТИТЕЛЬНЕЕ маршрут
-- грунтовки = высокий rate (предпочтительны)
-- асфальт = низкий rate (избегаем, но штраф 3-5x вместо 17-200x)
-- Примечание: footway/pedestrian/steps/corridor отсутствуют — они полностью исключены
-- из графа в process_way (ET-001, F-08).
local highway_rate = {
  track        = 100.0,   -- самый предпочтительный
  bridleway    = 90.0,
  path         = 85.0,
  cycleway     = 70.0,
  unclassified = 45.0,
  residential  = 35.0,
  service      = 28.0,
  tertiary     = 28.0,    -- было 6.0 → теперь ~3.5x хуже track
  tertiary_link= 28.0,
  secondary    = 22.0,    -- было 3.0 → теперь ~4.5x хуже track
  secondary_link = 22.0,
  primary      = 18.0,    -- было 1.5 → теперь ~5.5x хуже track
  primary_link = 18.0,
  trunk        = 12.0,    -- было 0.5
  trunk_link   = 12.0,
  motorway     = 5.0,     -- было 0.1
  motorway_link= 5.0,
}

-- Скорости (км/ч) — только для ETA (duration), не влияют на выбор маршрута
local highway_speeds = {
  track        = 30,
  bridleway    = 20,
  path         = 20,
  cycleway     = 25,
  unclassified = 40,
  residential  = 40,
  service      = 30,
  tertiary     = 60,
  tertiary_link= 60,
  secondary    = 70,
  secondary_link = 70,
  primary      = 80,
  primary_link = 80,
  trunk        = 90,
  trunk_link   = 90,
  motorway     = 110,
  motorway_link= 90,
}

-- Мультипликатор по качеству грунтовки (grade1 лучше grade5)
local tracktype_multiplier = {
  grade1 = 1.2,
  grade2 = 1.1,
  grade3 = 1.0,
  grade4 = 0.9,
  grade5 = 0.8,
}

-- ET-001 (F-07): полный запрет проезда через ноды-шлагбаумы.
-- cattle_grid и ford НЕ включены — мотоцикл их проходит.
local blocked_barriers = {
  gate                = true,
  bollard             = true,
  lift_gate           = true,
  chain               = true,
  cycle_barrier       = true,
  motorcycle_barrier  = true,
  border_control      = true,
  block               = true,
}

-- ET-001 (F-08): пешеходные/служебные типы дорог, полностью исключаемые из графа.
local excluded_highways = {
  footway    = true,
  pedestrian = true,
  steps      = true,
  corridor   = true,
}

function setup()
  return {
    properties = {
      weight_name        = 'routability',
      max_speed_for_map_matching = 30/3.6,
      call_tagless_node_function = false,
      traffic_light_penalty      = 2,
      u_turn_penalty             = 20,
      continue_straight_at_waypoint = false,
      use_turn_restrictions      = false,
    }
  }
end

-- ET-001 (F-07): шлагбаумы блокируются жёстко через mode.inaccessible.
-- Тег access не учитывается — физическое наличие шлагбаума уже причина обхода.
function process_node(profile, node, result)
  local barrier = node:get_value_by_key("barrier")
  if barrier and blocked_barriers[barrier] then
    result.barrier = true
    result.forward_mode  = mode.inaccessible
    result.backward_mode = mode.inaccessible
    return
  end
end

function process_way(profile, way, result)
  local highway = way:get_value_by_key("highway")
  if not highway then return end

  -- ET-001 (F-08): пешеходные/служебные типы — полностью убираем из графа.
  if excluded_highways[highway] then return end

  local rate = highway_rate[highway]
  if not rate then return end

  -- path/cycleway в городской застройке — исключить
  if highway == "path" or highway == "cycleway" then
    local landuse = way:get_value_by_key("landuse")
    local place = way:get_value_by_key("place")
    -- Признаки городской застройки
    if landuse == "residential" or landuse == "commercial" or landuse == "industrial" or
       place == "city" or place == "town" or place == "village" then
      return  -- исключить из графа
    end
  end

  local speed = highway_speeds[highway] or 30

  -- Мультипликатор по tracktype для грунтовок
  local tracktype = way:get_value_by_key("tracktype")
  if tracktype and tracktype_multiplier[tracktype] then
    rate = rate * tracktype_multiplier[tracktype]
  end

  result.forward_mode  = mode.driving
  result.backward_mode = mode.driving

  -- duration = реальное время (скорость в км/ч)
  result.forward_speed  = speed
  result.backward_speed = speed

  -- weight = distance / rate
  -- высокий rate → маленький weight → предпочтительный маршрут
  result.forward_rate  = rate
  result.backward_rate = rate

  -- Одностороннее движение
  local oneway = way:get_value_by_key("oneway")
  if oneway == "yes" or oneway == "1" or oneway == "true" then
    result.backward_mode = mode.inaccessible
  elseif oneway == "-1" then
    result.forward_mode = mode.inaccessible
  end
end

function process_turn(profile, turn)
  turn.duration = 0
  turn.weight   = 0

  if turn.is_u_turn then
    turn.duration = profile.properties.u_turn_penalty
    turn.weight   = profile.properties.u_turn_penalty
  end
end

return {
  setup        = setup,
  process_way  = process_way,
  process_node = process_node,
  process_turn = process_turn,
}
