content: /*
   * Copyright (C) 2006 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  //package com.google.webviewlocalserver.third_party.android;
  package com.getcapacitor;
  
  import android.net.Uri;
  import com.getcapacitor.util.HostMask;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.regex.Pattern;
  
  public class UriMatcher {
  
      /**
       * Creates the root node of the URI tree.
       *
       * @param code the code to match for the root URI
       */
      public UriMatcher(Object code) {
          mCode = code;
          mWhich = -1;
          mChildren = new ArrayList<>();
          mText = null;
      }
  
      private UriMatcher() {
          mCode = null;
          mWhich = -1;
          mChildren = new ArrayList<>();
          mText = null;
      }
  
      /**
       * Add a URI to match, and the code to return when this URI is
       * matched. URI nodes may be exact match string, the token "*"
       * that matches any text, or the token "#" that matches only
       * numbers.
       * <p>
       * Starting from API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
       * this method will accept a leading slash in the path.
       *
       * @param authority the authority to match
       * @param path      the path to match. * may be used as a wild card for
       *                  any text, and # may be used as a wild card for numbers.
       * @param code      the code that is returned when a URI is matched
       *                  against the given components. Must be positive.
       */
      public void addURI(String scheme, String authority, String path, Object code) {
          if (code == null) {
              throw new IllegalArgumentException("Code can't be null");
          }
  
          String[] tokens = null;
          if (path != null) {
              String newPath = path;
              // Strip leading slash if present.
              if (!path.isEmpty() && path.charAt(0) == '/') {
                  newPath = path.substring(1);
              }
              tokens = PATH_SPLIT_PATTERN.split(newPath);
          }
  
          int numTokens = tokens != null ? tokens.length : 0;
          UriMatcher node = this;
          for (int i = -2; i < numTokens; i++) {
              String token;
              if (i == -2) token = scheme; else if (i == -1) token = authority; else token = tokens[i];
              ArrayList<UriMatcher> children = node.mChildren;
              int numChildren = children.size();
              UriMatcher child;
              int j;
              for (j = 0; j < numChildren; j++) {
                  child = children.get(j);
                  if (token.equals(child.mText)) {
                      node = child;
                      break;
                  }
              }
              if (j == numChildren) {
                  // Child not found, create it
                  child = new UriMatcher();
                  if (i == -1 && token.contains("*")) {
                      child.mWhich = MASK;
                  } else if (token.equals("**")) {
                      child.mWhich = REST;
                  } else if (token.equals("*")) {
                      child.mWhich = TEXT;
                  } else {
                      child.mWhich = EXACT;
                  }
                  child.mText = token;
                  node.mChildren.add(child);
                  node = child;
              }
          }
          node.mCode = code;
      }
  
      static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/");
  
      /**
       * Try to match against the path in a url.
       *
       * @param uri The url whose path we will match against.
       * @return The code for the matched node (added using addURI),
       * or null if there is no matched node.
       */
      public Object match(Uri uri) {
          final List<String> pathSegments = uri.getPathSegments();
          final int li = pathSegments.size();
  
          UriMatcher node = this;
  
          if (li == 0 && uri.getAuthority() == null) {
              return this.mCode;
          }
  
          for (int i = -2; i < li; i++) {
              String u;
              if (i == -2) u = uri.getScheme(); else if (i == -1) u = uri.getAuthority(); else u = pathSegments.get(i);
              ArrayList<UriMatcher> list = node.mChildren;
              if (list == null) {
                  break;
              }
              node = null;
              int lj = list.size();
              for (int j = 0; j < lj; j++) {
                  UriMatcher n = list.get(j);
                  which_switch:switch (n.mWhich) {
                      case MASK:
                          if (HostMask.Parser.parse(n.mText).matches(u)) {
                              node = n;
                          }
                          break;
                      case EXACT:
                          if (n.mText.equals(u)) {
                              node = n;
                          }
                          break;
                      case TEXT:
                          node = n;
                          break;
                      case REST:
                          return n.mCode;
                  }
                  if (node != null) {
                      break;
                  }
              }
              if (node == null) {
                  return null;
              }
          }
  
          return node.mCode;
      }
  
      private static final int EXACT = 0;
      private static final int TEXT = 1;
      private static final int REST = 2;
      private static final int MASK = 3;
  
      private Object mCode;
      private int mWhich;
      private String mText;
      private ArrayList<UriMatcher> mChildren;
  }
  