/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.util.signature;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * A helper class for building exhaustive string descriptions of class, field, constructor, or
 * method declarations.
 *
 * @author Martin Zaun
 */
class Formatter {
  /** Returns a string formatting an array of names as comma-separated list. */
  public static String toString(String prefix, String[] names) {
    final StringBuilder s = new StringBuilder();
    if (names != null && names.length > 0) {
      s.append(prefix == null ? "" : prefix).append(names[0]);
      for (int i = 1; i < names.length; i++) {
        s.append(", ").append(names[i]);
      }
    }
    return s.toString();
  }

  /**
   * Returns a string formatting an array of class objects as comma-separated list of (Java) user
   * type names.
   */
  public static String toString(String prefix, Class<?>[] cls) {
    final StringBuilder s = new StringBuilder();
    if (cls != null && cls.length > 0) {
      String n = TypeHelper.userTypeName(cls[0].getName());
      s.append(prefix == null ? "" : prefix).append(n);
      for (int i = 1; i < cls.length; i++) {
        n = TypeHelper.userTypeName(cls[i].getName());
        s.append(", ").append(n);
      }
    }
    return s.toString();
  }

  /**
   * Returns an exhaustive string description of a <code>Field</code> presenting types as (Java)
   * user type names.
   */
  public static String toString(Field field, Object value) {
    final StringBuilder s = new StringBuilder();
    s.append(Modifier.toString(field.getModifiers())).append(" ");
    s.append(TypeHelper.userTypeName(field.getType().getName()));
    s.append(" ");
    s.append(field.getName());
    s.append(value == null ? "" : " = " + value);
    return s.toString();
  }

  /** Returns an combined string description of a field declaration. */
  public static String toString(int mods, String type, String name, String value) {
    final StringBuilder s = new StringBuilder();
    s.append(Modifier.toString(mods)).append(" ");
    s.append(type).append(" ");
    s.append(name);
    s.append(value == null ? "" : " = " + value);
    return s.toString();
  }

  /**
   * Returns an exhaustive string description of a <code>Constructor</code> presenting types as
   * (Java) user type names.
   */
  public static String toString(Constructor<?> ctor) {
    final StringBuilder s = new StringBuilder();
    s.append(Modifier.toString(ctor.getModifiers())).append(" ");
    s.append(ctor.getName()).append("(");
    s.append(toString("", ctor.getParameterTypes())).append(")");
    s.append(toString(" throws ", ctor.getExceptionTypes()));
    return s.toString();
  }

  /**
   * Returns an exhaustive string description of a <code>Method</code> presenting types as (Java)
   * user type names.
   */
  public static String toString(Method method) {
    final StringBuilder s = new StringBuilder();
    s.append(Modifier.toString(method.getModifiers())).append(" ");
    final String r = method.getReturnType().getName();
    s.append(TypeHelper.userTypeName(r)).append(" ");
    s.append(method.getName()).append("(");
    s.append(toString("", method.getParameterTypes())).append(")");
    s.append(toString(" throws ", method.getExceptionTypes()));
    if (method.getDeclaringClass().isAnnotation() && method.getDefaultValue() != null) {
      s.append(" default \"" + method.getDefaultValue() + "\"");
    }
    return s.toString();
  }

  /** Returns an combined string description of a constructor or method declaration. */
  public static String toString(
      int mods, String result, String name, String[] params, String[] excepts) {
    final StringBuilder s = new StringBuilder();
    s.append(Modifier.toString(mods)).append(" ");
    s.append(result == null ? "" : result).append(" ");
    s.append(name).append("(").append(toString("", params)).append(")");
    s.append(toString(" throws ", excepts));
    return s.toString();
  }

  /**
   * Returns an exhaustive string description of a <code>Class</code> presenting types as (Java)
   * user type names.
   */
  public static String toString(Class<?> cls) {
    final StringBuilder s = new StringBuilder();
    s.append(Modifier.toString(cls.getModifiers()));
    s.append(cls.isInterface() ? " " : " class ").append(cls.getName());
    final Class<?> superc = cls.getSuperclass();
    final Class<?>[] interf = cls.getInterfaces();
    if (cls.isInterface()) {
      s.append(toString(" extends ", interf));
    } else {
      s.append(superc == null ? "" : " extends " + superc.getName());
      s.append(toString(" implements ", interf));
    }
    return s.toString();
  }

  /** Returns an combined string description of a class header declaration. */
  public static String toString(int mods, String name, String[] ext, String[] impl) {
    final StringBuilder s = new StringBuilder();
    s.append(Modifier.toString(mods));
    final boolean isInterface = ((mods & Modifier.INTERFACE) != 0);
    s.append(isInterface ? " " : " class ").append(name);
    s.append(toString(" extends ", ext));
    s.append(toString(" implements ", impl));
    return s.toString();
  }

  /**
   * Returns an exhaustive string description of a <code>Member</code> presenting types as (Java)
   * user type names.
   */
  public static String toString(Member member) {
    final String s;
    if (member instanceof Field) {
      s = toString((Field) member, null);
    } else if (member instanceof Constructor) {
      s = toString((Constructor<?>) member);
    } else if (member instanceof Method) {
      s = toString((Method) member);
    } else {
      s = null;
    }
    return s;
  }
}
