findPossibleRoutes method

Map<String, int> findPossibleRoutes(
  1. Map<String, List<String>> query,
  2. String fragment,
  3. Map possibleSubroutes
)

Rates all route handlers for given query and possible subroutes

More matches for query params -> bigger rate value

Implementation

Map<String, int> findPossibleRoutes(
  Map<String, List<String>> query,
  String fragment,
  Map possibleSubroutes,
) {
  final decisionSubroutes = <String, int>{};

  if (query.isEmpty) {
    return decisionSubroutes;
  }

  final suggestions = possibleSubroutes.keys.map((element) {
    final subroute = element as String;

    if (!subroute.contains('|')) {
      for (final queryParam in query.entries) {
        if (_checkSubroute(subroute, queryParam.key, queryParam.value)) {
          return MapEntry(subroute, 1);
        }
      }

      return MapEntry(subroute, 0);
    }

    var canBeSelectedQueryParams = 0;
    final alreadyChecked = <String>[];
    final rules = subroute.split('|');

    for (final rule in rules) {
      var queryCheckResult = 0;

      if (rule.startsWith('#')) {
        final ruleKey = rule.split('=')[0];

        if (alreadyChecked.contains(ruleKey)) {
          continue;
        }

        final requiredRules = rules.where(
          (element) => element.contains('$ruleKey='),
        );

        var ruleIsSatisfied = false;

        for (final requiredRule in requiredRules) {
          if (requiredRule.substring(2) == fragment) {
            ruleIsSatisfied = true;
            break;
          }
        }

        if (!ruleIsSatisfied) {
          canBeSelectedQueryParams = 0;
          break;
        } else {
          canBeSelectedQueryParams++;
          alreadyChecked.add(ruleKey);
        }
      } else if (rule.contains('=')) {
        final ruleKey = rule.split('=')[0];

        if (alreadyChecked.contains(ruleKey)) {
          continue;
        }

        final requiredRules = rules.where(
          (element) => element.contains('$ruleKey='),
        );

        var ruleIsSatisfied = false;

        for (final requiredRule in requiredRules) {
          if (query.entries.where((element) {
            final formattedQuery = element.value.length != 1
                ? '${element.key}=${element.value}'
                : '${element.key}=${element.value[0]}';

            return requiredRule == formattedQuery;
          }).isNotEmpty) {
            ruleIsSatisfied = true;
            break;
          }
        }

        if (!ruleIsSatisfied) {
          canBeSelectedQueryParams = 0;
          break;
        } else {
          canBeSelectedQueryParams++;
          alreadyChecked.add(ruleKey);
        }
      } else {
        for (final queryParam in query.entries) {
          if (alreadyChecked.contains(queryParam.key)) {
            continue;
          }

          final routeCheckResult = _checkSubroute(
            rule,
            queryParam.key,
            queryParam.value,
          );

          if (routeCheckResult) {
            queryCheckResult++;
            canBeSelectedQueryParams++;
            alreadyChecked.add(queryParam.key);
          }
        }

        if (queryCheckResult == 0 && !rule.contains('?')) {
          canBeSelectedQueryParams = 0;
          break;
        }
      }

      queryCheckResult = 0;
    }

    return MapEntry(subroute, canBeSelectedQueryParams);
  });

  for (final element in suggestions) {
    decisionSubroutes[element.key] = element.value;
  }

  return decisionSubroutes;
}