/*
 * Copyright (C) 2014 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.
 */

// These classes are to check the additional flags for inner classes.
class A {
  private static class B {
  }
  protected static interface C {
  }
}

public class Main {
  public final static int INTERFACE_DEFINED_BITS =
      0x0001 |  // public, may be set.
      0x0002 |  // private, may be flagged by inner class.
      0x0004 |  // protected, may be flagged by inner class.
      0x0008 |  // static, may be flagged by inner class.
      0x0010 |  // final, must not be set.
      0x0020 |  // super, must not be set.
      0x0200 |  // interface, must be set.
      0x0400 |  // abstract, must be set.
      0x1000 |  // synthetic, may be set.
      0x2000 |  // annotation, may be set (annotation implies interface)
      0x4000 ;  // enum, must not be set.

  public final static int CLASS_DEFINED_BITS =
      0x0001 |  // public, may be set.
      0x0002 |  // private, may be flagged by inner class.
      0x0004 |  // protected, may be flagged by inner class.
      0x0008 |  // static, may be flagged by inner class.
      0x0010 |  // final, may be set.
      0x0020 |  // super, may be set.
      0x0200 |  // interface, must not be set.
      0x0400 |  // abstract, may be set.
      0x1000 |  // synthetic, may be set.
      0x2000 |  // annotation, must not be set.
      0x4000 ;  // enum, may be set.

  public final static int FIELD_DEFINED_BITS =
       0x0001 |  // public
       0x0002 |  // private
       0x0004 |  // protected
       0x0008 |  // static
       0x0010 |  // final
       0x0040 |  // volatile
       0x0080 |  // transient
       0x1000 |  // synthetic
       0x4000 ;  // enum

  public final static int METHOD_DEFINED_BITS =
       0x0001 |  // public
       0x0002 |  // private
       0x0004 |  // protected
       0x0008 |  // static
       0x0010 |  // final
       0x0020 |  // synchronized
       0x0040 |  // bridge
       0x0080 |  // varargs
       0x0100 |  // native
       0x0400 |  // abstract
       0x0800 |  // strictfp
       0x1000 ;  // synthetic

  public static void main(String args[]) throws Exception {
    check("Inf");
    check("NonInf");
    check("A");
    check("A$B");
  }

  private static void check(String className) throws Exception {
    Class<?> clazz = Class.forName(className);
    if (className.equals("Inf")) {
      if (!clazz.isInterface()) {
        throw new RuntimeException("Expected an interface.");
      }
      int undefinedBits = 0xFFFF ^ INTERFACE_DEFINED_BITS;
      if ((clazz.getModifiers() & undefinedBits) != 0) {
        System.out.println("Clazz.getModifiers(): " + Integer.toBinaryString(clazz.getModifiers()));
        System.out.println("INTERFACE_DEF_BITS: " + Integer.toBinaryString(INTERFACE_DEFINED_BITS));
        throw new RuntimeException("Undefined bits for an interface: " + className);
      }
    } else {
      if (clazz.isInterface()) {
        throw new RuntimeException("Expected a class.");
      }
      int undefinedBits = 0xFFFF ^ CLASS_DEFINED_BITS;
      if ((clazz.getModifiers() & undefinedBits) != 0) {
        System.out.println("Clazz.getModifiers(): " + Integer.toBinaryString(clazz.getModifiers()));
        System.out.println("CLASS_DEF_BITS: " + Integer.toBinaryString(CLASS_DEFINED_BITS));
        throw new RuntimeException("Undefined bits for a class: " + className);
      }
    }

    // Check fields.
    for (java.lang.reflect.Field f : clazz.getDeclaredFields()) {
      String name = f.getName();
      int undefinedBits = 0xFFFF ^ FIELD_DEFINED_BITS;
      if ((f.getModifiers() & undefinedBits) != 0) {
        System.out.println("f.getModifiers(): " + Integer.toBinaryString(f.getModifiers()));
        System.out.println("FIELD_DEF_BITS: " + Integer.toBinaryString(FIELD_DEFINED_BITS));
        throw new RuntimeException("Unexpected field bits: " + name);
      }
      if (name.equals("I")) {
        // Interface field, just check generically.
      } else {
        // Check the name, see that the corresponding bit is set.
        int bitmask = getFieldMask(name);
        if ((bitmask & f.getModifiers()) == 0) {
          throw new RuntimeException("Expected field bit not set.");
        }
      }
    }

    // Check methods.
    for (java.lang.reflect.Method m : clazz.getDeclaredMethods()) {
      String name = m.getName();
      int undefinedBits = 0xFFFF ^ METHOD_DEFINED_BITS;
      if ((m.getModifiers() & undefinedBits) != 0) {
          System.out.println("m.getModifiers(): " + Integer.toBinaryString(m.getModifiers()));
          System.out.println("METHOD_DEF_BITS: " + Integer.toBinaryString(METHOD_DEFINED_BITS));
        throw new RuntimeException("Unexpected method bits: " + name);
      }
      // Check the name, see that the corresponding bit is set.
      int bitmask = getMethodMask(name);
      if ((bitmask & m.getModifiers()) == 0) {
        throw new RuntimeException("Expected method bit not set.");
      }
    }
  }

  private static int getFieldMask(String name) {
    int index = name.indexOf("Field");
    if (index > 0) {
      String shortS = name.substring(0, index);
      if (shortS.equals("public")) {
        return 0x0001;
      }
      if (shortS.equals("private")) {
        return 0x0002;
      }
      if (shortS.equals("protected")) {
        return 0x0004;
      }
      if (shortS.equals("static")) {
        return 0x0008;
      }
      if (shortS.equals("transient")) {
        return 0x0080;
      }
      if (shortS.equals("volatile")) {
        return 0x0040;
      }
      if (shortS.equals("final")) {
        return 0x0010;
      }
    }
    throw new RuntimeException("Unexpected field name " + name);
  }

  private static int getMethodMask(String name) {
    int index = name.indexOf("Method");
    if (index > 0) {
      String shortS = name.substring(0, index);
      if (shortS.equals("public")) {
        return 0x0001;
      }
      if (shortS.equals("private")) {
        return 0x0002;
      }
      if (shortS.equals("protected")) {
        return 0x0004;
      }
      if (shortS.equals("static")) {
        return 0x0008;
      }
      if (shortS.equals("synchronized")) {
        return 0x0020;
      }
      if (shortS.equals("varargs")) {
        return 0x0080;
      }
      if (shortS.equals("final")) {
        return 0x0010;
      }
      if (shortS.equals("native")) {
        return 0x0100;
      }
      if (shortS.equals("abstract")) {
        return 0x0400;
      }
      if (shortS.equals("strictfp")) {
        return 0x0800;
      }
    }
    throw new RuntimeException("Unexpected method name " + name);
  }
}
