buildUri function

Uri buildUri(
  1. String? scheme,
  2. String? host,
  3. int? port, {
  4. String? path,
  5. String? path2,
  6. String? queryString,
  7. String? fragment,
})

Builds an Uri with the parameters.

path2 appends to path. If starts with / overwrites it.

Implementation

Uri buildUri(String? scheme, String? host, int? port,
    {String? path, String? path2, String? queryString, String? fragment}) {
  var base = getUriBase();

  if (isEmptyString(scheme)) scheme = base.scheme;
  if (isEmptyString(host)) host = base.host;

  var defaultPort = scheme == 'https' ? 443 : (scheme == 'http' ? 80 : 0);

  if (port == null || port == 0) {
    port = scheme == base.scheme && host == base.host ? base.port : defaultPort;
  }

  path ??= '/';
  if (!path.startsWith('/')) path = '/$path';

  if (queryString == '') queryString = null;

  if (fragment == '') fragment = null;

  // path fragment:

  var idx = path.indexOf('#');

  var fragmentFromPath = false;

  if (idx >= 0) {
    var pathFragment = path.substring(idx + 1);

    if (pathFragment.isNotEmpty) {
      if (fragment == null) {
        fragment = pathFragment;
      } else {
        fragment = '$pathFragment&$fragment';
      }

      fragmentFromPath = true;
    }

    path = path.substring(0, idx);
  }

  // path queryString:

  var queryStringFromPath = false;

  idx = path.indexOf('?');
  if (idx >= 0) {
    var pathQuery = path.substring(idx + 1);

    if (pathQuery.isNotEmpty) {
      if (queryString == null) {
        queryString = pathQuery;
      } else {
        queryString = '$pathQuery&$queryString';
      }

      queryStringFromPath = true;
    }

    path = path.substring(0, idx);
  }

  // path2

  if (path2 != null) {
    // path2 fragment:

    idx = path2.indexOf('#');

    if (idx >= 0) {
      var path2Fragment = path2.substring(idx + 1);

      if (path2Fragment.isNotEmpty) {
        if (fragment == null) {
          fragment = path2Fragment;
        } else {
          if (fragmentFromPath) {
            fragment = path2Fragment;
          } else {
            fragment = '$path2Fragment&$fragment';
          }
        }

        fragmentFromPath = false;
      }

      path2 = path2.substring(0, idx);
    }

    if (fragmentFromPath) {
      fragment = null;
    }

    // path2 queryString:

    idx = path2.indexOf('?');

    if (idx >= 0) {
      var path2Query = path2.substring(idx + 1);

      if (path2Query.isNotEmpty) {
        if (queryString == null) {
          queryString = path2Query;
        } else {
          if (queryStringFromPath) {
            queryString = path2Query;
          } else {
            queryString = '$path2Query&$queryString';
          }
        }

        queryStringFromPath = false;
      }

      path2 = path2.substring(0, idx);
    }

    if (queryStringFromPath) {
      queryString = null;
    }

    // path + path2:

    if (path2.isNotEmpty) {
      if (path2.startsWith('/')) {
        path = path2;
      } else {
        if (!path.endsWith('/')) {
          idx = path.lastIndexOf('/');
          if (idx >= 0) {
            path = path.substring(0, idx + 1);
          } else {
            path = '/';
          }
        }

        if (path2.startsWith('./')) {
          path += path2.substring(2);
        } else {
          path += path2;
        }
      }
    }
  }

  var resolved = port == defaultPort
      ? Uri(
          scheme: scheme,
          host: host,
          path: path,
          query: queryString,
          fragment: fragment)
      : Uri(
          scheme: scheme,
          host: host,
          port: port,
          path: path,
          query: queryString,
          fragment: fragment);

  return resolved;
}