/**
   * Detects the current-user-principal for a given WebDavResource. At first, /.well-known/ is
   * tried. Only if no current-user-principal can be detected for the .well-known location, the
   * given location of the resource is tried.
   *
   * @param serverInfo Location that will be queried
   * @param serviceName Well-known service name ("carddav", "caldav")
   * @return WebDavResource of current-user-principal for the given service, or null if it can't be
   *     found
   *     <p>TODO: If a TXT record is given, always use it instead of trying .well-known first
   */
  WebDavResource getCurrentUserPrincipal(ServerInfo serverInfo, String serviceName)
      throws URISyntaxException, IOException, NotAuthorizedException {
    URI initialURL = getInitialContextURL(serverInfo, serviceName);
    if (initialURL != null) {
      Log.i(
          TAG,
          "Looking up principal URL for service "
              + serviceName
              + "; initial context: "
              + initialURL);

      // determine base URL (host name and initial context path)
      WebDavResource base =
          new WebDavResource(
              httpClient,
              initialURL,
              serverInfo.getUserName(),
              serverInfo.getPassword(),
              serverInfo.isAuthPreemptive());

      // look for well-known service (RFC 5785)
      try {
        WebDavResource wellKnown = new WebDavResource(base, "/.well-known/" + serviceName);
        wellKnown.propfind(Mode.CURRENT_USER_PRINCIPAL);
        if (wellKnown.getProperties().getCurrentUserPrincipal() != null) {
          URI principal = wellKnown.getProperties().getCurrentUserPrincipal();
          Log.i(TAG, "Principal URL found from Well-Known URI: " + principal);
          return new WebDavResource(wellKnown, principal);
        }
      } catch (NotAuthorizedException e) {
        Log.w(TAG, "Not authorized for well-known " + serviceName + " service detection", e);
        throw e;
      } catch (URISyntaxException e) {
        Log.e(
            TAG,
            "Well-known" + serviceName + " service detection failed because of invalid URIs",
            e);
      } catch (HttpException e) {
        Log.d(TAG, "Well-known " + serviceName + " service detection failed with HTTP error", e);
      } catch (DavException e) {
        Log.w(
            TAG,
            "Well-known " + serviceName + " service detection failed with unexpected DAV response",
            e);
      } catch (IOException e) {
        Log.e(TAG, "Well-known " + serviceName + " service detection failed with I/O error", e);
      }

      // fall back to user-given initial context path
      Log.d(TAG, "Well-known service detection failed, trying initial context path " + initialURL);
      try {
        base.propfind(Mode.CURRENT_USER_PRINCIPAL);
        if (base.getProperties().getCurrentUserPrincipal() != null) {
          URI principal = base.getProperties().getCurrentUserPrincipal();
          Log.i(TAG, "Principal URL found from initial context path: " + principal);
          return new WebDavResource(base, principal);
        }
      } catch (NotAuthorizedException e) {
        Log.e(TAG, "Not authorized for querying principal", e);
        throw e;
      } catch (HttpException e) {
        Log.e(TAG, "HTTP error when querying principal", e);
      } catch (DavException e) {
        Log.e(TAG, "DAV error when querying principal", e);
      }

      Log.i(
          TAG,
          "Couldn't find current-user-principal for service "
              + serviceName
              + ", assuming initial context path is principal path");
      return base;
    }
    return null;
  }