content: /*
   * Copyright (C) 2018 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 androidx.constraintlayout.motion.widget;
  
  import android.annotation.SuppressLint;
  import android.content.Context;
  import android.content.res.Resources;
  import android.util.Log;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  
  import java.lang.reflect.Field;
  import java.nio.CharBuffer;
  
  // @TODO: add description
  
  /**
   * Utilities useful for debugging
   *
   */
  @SuppressLint("LogConditional")
  public class Debug {
  
      /**
       * This logs n elements in the stack
       *
       * @param tag
       * @param msg
       * @param n
       *
       */
      public static void logStack(String tag, String msg, int n) {
          StackTraceElement[] st = new Throwable().getStackTrace();
          String s = " ";
          n = Math.min(n, st.length - 1);
          for (int i = 1; i <= n; i++) {
              @SuppressWarnings("unused") StackTraceElement ste = st[i];
              String stack = ".(" + st[i].getFileName() + ":" + st[i].getLineNumber()
                      + ") " + st[i].getMethodName();
              s += " ";
              Log.v(tag, msg + s + stack + s);
          }
      }
  
      /**
       * This logs n elements in the stack
       *
       * @param msg
       * @param n
       *
       */
      public static void printStack(String msg, int n) {
          StackTraceElement[] st = new Throwable().getStackTrace();
          String s = " ";
          n = Math.min(n, st.length - 1);
          for (int i = 1; i <= n; i++) {
              @SuppressWarnings("unused") StackTraceElement ste = st[i];
              String stack = ".(" + st[i].getFileName() + ":" + st[i].getLineNumber() + ") ";
              s += " ";
              System.out.println(msg + s + stack + s);
          }
      }
  
      /**
       * This provides return the name of a view
       *
       * @param view
       * @return name of view
       *
       */
      public static String getName(View view) {
          try {
              Context context = view.getContext();
              return context.getResources().getResourceEntryName(view.getId());
          } catch (Exception ex) {
              return "UNKNOWN";
          }
      }
  
      // @TODO: add description
  
      /**
       * @param obj
       */
      public static void dumpPoc(Object obj) {
          StackTraceElement s = new Throwable().getStackTrace()[1];
          String loc = ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
          Class c = obj.getClass();
          System.out.println(loc + "------------- " + c.getName() + " --------------------");
          Field[] declaredFields = c.getFields();
          for (int i = 0; i < declaredFields.length; i++) {
              Field declaredField = declaredFields[i];
  
              try {
                  Object value = declaredField.get(obj);
                  if (!declaredField.getName().startsWith("layout_constraint")) {
                      continue;
                  }
                  if (value instanceof Integer && value.toString().equals("-1")) {
                      continue;
                  }
                  if (value instanceof Integer && value.toString().equals("0")) {
                      continue;
                  }
                  if (value instanceof Float && value.toString().equals("1.0")) {
                      continue;
                  }
                  if (value instanceof Float && value.toString().equals("0.5")) {
                      continue;
                  }
                  System.out.println(loc + "    " + declaredField.getName() + " " + value);
              } catch (IllegalAccessException e) {
  
              }
  
          }
          System.out.println(loc + "------------- " + c.getSimpleName() + " --------------------");
  
      }
  
      /**
       * This returns the name of a view given its id
       *
       * @param context
       * @param id
       * @return name of view
       *
       */
      public static String getName(Context context, int id) {
          try {
              if (id != -1) {
                  return context.getResources().getResourceEntryName(id);
              } else {
                  return "UNKNOWN";
              }
          } catch (Exception ex) {
              return "?" + id;
          }
      }
  
      /**
       * This returns the name of a view given its id
       *
       * @param context
       * @param id
       * @return name of view
       *
       */
      public static String getName(Context context, int[] id) {
          try {
              String str = id.length + "[";
              for (int i = 0; i < id.length; i++) {
                  str += (i == 0) ? "" : " ";
                  String tmp = null;
                  try {
                      tmp = context.getResources().getResourceEntryName(id[i]);
                  } catch (Resources.NotFoundException e) {
                      tmp = "? " + id[i] + " ";
                  }
  
                  str += tmp;
  
              }
              return str + "]";
          } catch (Exception ex) {
              Log.v("DEBUG", ex.toString());
              return "UNKNOWN";
          }
      }
  
      /**
       * convert an id number to an id String useful in debugging
       *
       * @param layout
       * @param stateId
       * @return
       */
      public static String getState(MotionLayout layout, int stateId) {
          return getState(layout, stateId, -1);
      }
  
      /**
       * convert an id number to an id String useful in debugging
       *
       * @param layout
       * @param stateId
       * @param len     trim if string > len
       * @return
       */
      public static String getState(MotionLayout layout, int stateId, int len) {
          if (stateId == -1) {
              return "UNDEFINED";
          }
          Context context = layout.getContext();
          String str = context.getResources().getResourceEntryName(stateId);
          if (len != -1) {
              if (str.length() > len) {
                  str = str.replaceAll("([^_])[aeiou]+", "$1"); // del vowels ! at start
              }
              if (str.length() > len) {
                  int n = str.replaceAll("[^_]", "").length(); // count number of "_"
                  if (n > 0) {
                      int extra = (str.length() - len) / n;
                      String reg = CharBuffer.allocate(extra).toString().replace('\0', '.') + "_";
                      str = str.replaceAll(reg, "_");
                  }
              }
          }
          return str;
      }
  
      /**
       * Convert a motion event action to a string
       *
       * @param event
       * @return
       */
      public static String getActionType(MotionEvent event) {
          int type = event.getAction();
          Field[] fields = MotionEvent.class.getFields();
          for (int i = 0; i < fields.length; i++) {
              Field field = fields[i];
              try {
                  if (java.lang.reflect.Modifier.isStatic(field.getModifiers())
                          && field.getType().equals(Integer.TYPE)
                          && field.getInt(null) == type) {
                      return field.getName();
                  }
              } catch (IllegalAccessException e) {
              }
          }
          return "---";
      }
  
      /**
       * Get file name and location where this method is called.
       * Formatting it such that it is clickable by Intellij
       *
       * @return (filename : line_no)
       */
      public static String getLocation() {
          StackTraceElement s = new Throwable().getStackTrace()[1];
          return ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
      }
  
      /**
       * Get file name and location where this method is called.
       * Formatting it such that it is clickable by Intellij
       *
       * @return (filename : line_no)
       */
      public static String getLoc() {
          StackTraceElement s = new Throwable().getStackTrace()[1];
          return ".(" + s.getFileName() + ":" + s.getLineNumber() + ") " + s.getMethodName() + "()";
      }
  
      /**
       * Get file name and location where this method is called.
       * Formatting it such that it is clickable by Intellij
       *
       * @return (filename : line_no)
       */
      public static String getLocation2() {
          StackTraceElement s = new Throwable().getStackTrace()[2];
          return ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
      }
  
      /**
       * Get file name and location where this method is called.
       * Formatting it such that it is clickable by Intellij
       *
       * @return (filename : line_no)
       */
      public static String getCallFrom(int n) {
          StackTraceElement s = new Throwable().getStackTrace()[2 + n];
          return ".(" + s.getFileName() + ":" + s.getLineNumber() + ")";
      }
  
      // @TODO: add description
  
      /**
       *
       * @param layout
       * @param str
       */
      public static void dumpLayoutParams(ViewGroup layout, String str) {
          StackTraceElement s = new Throwable().getStackTrace()[1];
          String loc = ".(" + s.getFileName() + ":" + s.getLineNumber() + ") " + str + "  ";
          int n = layout.getChildCount();
          System.out.println(str + " children " + n);
          for (int i = 0; i < n; i++) {
              View v = layout.getChildAt(i);
              System.out.println(loc + "     " + getName(v));
              ViewGroup.LayoutParams param = v.getLayoutParams();
              Field[] declaredFields = param.getClass().getFields();
              for (int k = 0; k < declaredFields.length; k++) {
                  Field declaredField = declaredFields[k];
  
                  try {
                      Object value = declaredField.get(param);
                      String name = declaredField.getName();
                      if (!name.contains("To")) {
                          continue;
                      }
                      if (value.toString().equals("-1")) {
                          continue;
                      }
  
                      System.out.println(loc + "       " + declaredField.getName() + " " + value);
                  } catch (IllegalAccessException e) {
  
                  }
  
              }
  
          }
      }
  
      // @TODO: add description
  
      /**
       *
       * @param param
       * @param str
       */
      public static void dumpLayoutParams(ViewGroup.LayoutParams param, String str) {
          StackTraceElement s = new Throwable().getStackTrace()[1];
          String loc = ".(" + s.getFileName() + ":" + s.getLineNumber() + ") " + str + "  ";
          System.out.println(" >>>>>>>>>>>>>>>>>>. dump " + loc + "  " + param.getClass().getName());
  
          Field[] declaredFields = param.getClass().getFields();
          for (int k = 0; k < declaredFields.length; k++) {
              Field declaredField = declaredFields[k];
  
              try {
                  Object value = declaredField.get(param);
                  String name = declaredField.getName();
                  if (!name.contains("To")) {
                      continue;
                  }
                  if (value.toString().equals("-1")) {
                      continue;
                  }
  //                    if (value instanceof  Integer && value.toString().equals("-1")) {
  //                        continue;
  //                    }
  
                  System.out.println(loc + "       " + name + " " + value);
              } catch (IllegalAccessException e) {
  
              }
  
          }
          System.out.println(" <<<<<<<<<<<<<<<<< dump " + loc);
  
      }
  }
  