<commit_before>package org.mtransit.parser.mt

import org.mtransit.commons.containsExactList
import org.mtransit.commons.indexOf
import org.mtransit.commons.lastIndexOf
import org.mtransit.parser.Constants
import org.mtransit.parser.LocationUtils
import org.mtransit.parser.MTLog
import org.mtransit.parser.StringUtils.EMPTY
import org.mtransit.parser.gtfs.GAgencyTools
import org.mtransit.parser.gtfs.data.GIDs
import org.mtransit.parser.gtfs.data.GSpec
import org.mtransit.parser.gtfs.data.GStop
import org.mtransit.parser.gtfs.data.GStopTime
import org.mtransit.parser.gtfs.data.GStopTime.Companion.maxStopSequence
import org.mtransit.parser.gtfs.data.GStopTime.Companion.minStopSequence
import org.mtransit.parser.gtfs.data.GTime
import org.mtransit.parser.gtfs.data.GTrip
import org.mtransit.parser.mt.data.MTrip
import kotlin.math.abs
import kotlin.math.max

private const val LOG_MERGE = false
// private const val LOG_MERGE = true // DEBUG

private const val MAX_DISTANCE_TO_BE_SAME_TRANSIT_HUB_IN_METERS = 25.0f

object MDirectionHeadSignFinder {

    @JvmStatic
    fun findDirectionHeadSigns(routeId: Long, gRouteTrips: List<GTrip>, routeGTFS: GSpec, agencyTools: GAgencyTools): Map<Int, String> {
        val directionHeadSigns = mutableMapOf<Int, String>()
        val directionStopIdInts = mutableMapOf<Int, Int>()
        val directionAmPm = mutableMapOf<Int, Pair<Int, Int>?>()
        var directionIdOrDefault: Int = -1
        findDirectionHeadSign(routeId, gRouteTrips, routeGTFS, directionIdOrDefault, agencyTools)?.let { (headSign, stopIdInt, firstAndLast) ->
            directionHeadSigns[directionIdOrDefault] = headSign
            directionStopIdInts[directionIdOrDefault] = stopIdInt
            directionAmPm[directionIdOrDefault] = firstAndLast
        }
        directionIdOrDefault = 0
        findDirectionHeadSign(routeId, gRouteTrips, routeGTFS, directionIdOrDefault, agencyTools)?.let { (headSign, stopIdInt, firstAndLast) ->
            directionHeadSigns[directionIdOrDefault] = headSign
            directionStopIdInts[directionIdOrDefault] = stopIdInt
            directionAmPm[directionIdOrDefault] = firstAndLast
        }
        directionIdOrDefault = 1
        findDirectionHeadSign(routeId, gRouteTrips, routeGTFS, directionIdOrDefault, agencyTools)?.let { (headSign, stopIdInt, firstAndLast) ->
            directionHeadSigns[directionIdOrDefault] = headSign
            directionStopIdInts[directionIdOrDefault] = stopIdInt
            directionAmPm[directionIdOrDefault] = firstAndLast
        }
        if (!agencyTools.directionHeadSignsDescriptive(directionHeadSigns)) {
            MTLog.log("$routeId: Direction from trip head-sign '$directionHeadSigns' not descriptive, using AM/PM...")
            for ((directionId, _) in directionHeadSigns) {
                val firstAndLastTime = directionAmPm[directionId] ?: continue
                if (GTime.areAM(firstAndLastTime)) {
                    directionHeadSigns[directionId] = agencyTools.cleanDirectionHeadsign(
                        true,<commit_msg>GTFS Direction Finder > AM/PM only for 2 directions<commit_after>package org.mtransit.parser.mt

import org.mtransit.commons.containsExactList
import org.mtransit.commons.indexOf
import org.mtransit.commons.lastIndexOf
import org.mtransit.parser.Constants
import org.mtransit.parser.LocationUtils
import org.mtransit.parser.MTLog
import org.mtransit.parser.StringUtils.EMPTY
import org.mtransit.parser.gtfs.GAgencyTools
import org.mtransit.parser.gtfs.data.GIDs
import org.mtransit.parser.gtfs.data.GSpec
import org.mtransit.parser.gtfs.data.GStop
import org.mtransit.parser.gtfs.data.GStopTime
import org.mtransit.parser.gtfs.data.GStopTime.Companion.maxStopSequence
import org.mtransit.parser.gtfs.data.GStopTime.Companion.minStopSequence
import org.mtransit.parser.gtfs.data.GTime
import org.mtransit.parser.gtfs.data.GTrip
import org.mtransit.parser.mt.data.MTrip
import kotlin.math.abs
import kotlin.math.max

private const val LOG_MERGE = false
// private const val LOG_MERGE = true // DEBUG

private const val MAX_DISTANCE_TO_BE_SAME_TRANSIT_HUB_IN_METERS = 25.0f

object MDirectionHeadSignFinder {

    @JvmStatic
    fun findDirectionHeadSigns(routeId: Long, gRouteTrips: List<GTrip>, routeGTFS: GSpec, agencyTools: GAgencyTools): Map<Int, String> {
        val directionHeadSigns = mutableMapOf<Int, String>()
        val directionStopIdInts = mutableMapOf<Int, Int>()
        val directionAmPm = mutableMapOf<Int, Pair<Int, Int>?>()
        var directionIdOrDefault: Int = -1
        findDirectionHeadSign(routeId, gRouteTrips, routeGTFS, directionIdOrDefault, agencyTools)?.let { (headSign, stopIdInt, firstAndLast) ->
            directionHeadSigns[directionIdOrDefault] = headSign
            directionStopIdInts[directionIdOrDefault] = stopIdInt
            directionAmPm[directionIdOrDefault] = firstAndLast
        }
        directionIdOrDefault = 0
        findDirectionHeadSign(routeId, gRouteTrips, routeGTFS, directionIdOrDefault, agencyTools)?.let { (headSign, stopIdInt, firstAndLast) ->
            directionHeadSigns[directionIdOrDefault] = headSign
            directionStopIdInts[directionIdOrDefault] = stopIdInt
            directionAmPm[directionIdOrDefault] = firstAndLast
        }
        directionIdOrDefault = 1
        findDirectionHeadSign(routeId, gRouteTrips, routeGTFS, directionIdOrDefault, agencyTools)?.let { (headSign, stopIdInt, firstAndLast) ->
            directionHeadSigns[directionIdOrDefault] = headSign
            directionStopIdInts[directionIdOrDefault] = stopIdInt
            directionAmPm[directionIdOrDefault] = firstAndLast
        }
        if (directionHeadSigns.size == 2 // AM/PM only if 2 directions
            && !agencyTools.directionHeadSignsDescriptive(directionHeadSigns)
        ) {
            MTLog.log("$routeId: Direction from trip head-sign '$directionHeadSigns' not descriptive, using AM/PM...")
            for ((directionId, _) in directionHeadSigns) {
                val firstAndLastTime = directionAmPm[directionId] ?: continue
                if (GTime.areAM(firstAndLastTime)) {
                    directionHeadSigns[directionId] = agencyTools.cleanDirectionHeadsign(
                        true,
{'fraction_non_alphanumeric': 0.08454763811048839, 'fraction_numerical': 0.0024019215372297837, 'mean_word_length': 3.8381099922540667, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '374474', 'n_tokens_mistral': 1920, 'n_tokens_neox': 1886, 'n_words': 329}