/*
 *******************************************************************************
 * Copyright (C) 2014, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.tool.docs;

import java.io.File;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

public class DeprecatedAPIChecker {

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Illegal command argument. Specify the API signature file path.");
        }
        // Load the ICU4J API signature file
        Set<APIInfo> apiInfoSet = APIData.read(new File(args[0]), true).getAPIInfoSet();

        DeprecatedAPIChecker checker = new DeprecatedAPIChecker(apiInfoSet, new PrintWriter(System.err, true));
        checker.checkDeprecated();
        System.exit(checker.errCount);
    }

    private int errCount = 0;
    private Set<APIInfo> apiInfoSet;
    private PrintWriter pw;

    public DeprecatedAPIChecker(Set<APIInfo> apiInfoSet, PrintWriter pw) {
        this.apiInfoSet = apiInfoSet;
        this.pw = pw;
    }

    public int errorCount() {
        return errCount;
    }

    public void checkDeprecated() {
        // Gather API class/enum names and its names that can be
        // used for Class.forName()
        Map<String, String> apiClassNameMap = new TreeMap<String, String>();
        for (APIInfo api : apiInfoSet) {
            if (!api.isPublic() && !api.isProtected()) {
                continue;
            }
            if (!api.isClass() && !api.isEnum()) {
                continue;
            }
            String packageName = api.getPackageName();
            String className = api.getName();

            // Replacing separator for nested class/enum (replacing '.' with
            // '$'), so we can use the name for Class.forName(String)
            String classNamePath = className.contains(".") ? className.replace('.', '$') : className;

            apiClassNameMap.put(packageName + "." + classNamePath, packageName + "." + className);
        }

        // Walk through API classes using reflection
        for (Entry<String, String> classEntry : apiClassNameMap.entrySet()) {
            String classNamePath = classEntry.getKey();
            try {
                Class<?> cls = Class.forName(classNamePath);
                if (cls.isEnum()) {
                    checkEnum(cls, apiClassNameMap);
                } else {
                    checkClass(cls, apiClassNameMap);
                }
            } catch (ClassNotFoundException e) {
                pw.println("## Error ## Class " + classNamePath + " is not found.");
                errCount++;
            }
        }
    }

    private void checkClass(Class<?> cls, Map<String, String> clsNameMap) {
        assert !cls.isEnum();

        String clsPath = cls.getName();
        String clsName = clsNameMap.get(clsPath);
        APIInfo api = null;

        if (clsName != null) {
            api = findClassInfo(apiInfoSet, clsName);
        }
        if (api == null) {
            pw.println("## Error ## Class " + clsName + " is not found in the API signature data.");
            errCount++;
        }

        // check class
        compareDeprecated(isAPIDeprecated(api), cls.isAnnotationPresent(Deprecated.class), clsName, null, "Class");

        // check fields
        for (Field f : cls.getDeclaredFields()) {
            if (!isPublicOrProtected(f.getModifiers())) {
                continue;
            }

            String fName = f.getName();
            api = findFieldInfo(apiInfoSet, clsName, fName);
            if (api == null) {
                pw.println("## Error ## Field " + clsName + "." + fName + " is not found in the API signature data.");
                errCount++;
                continue;
            }

            compareDeprecated(isAPIDeprecated(api), f.isAnnotationPresent(Deprecated.class), clsName, fName, "Field");
        }

        // check constructors
        for (Constructor<?> ctor : cls.getDeclaredConstructors()) {
            if (!isPublicOrProtected(ctor.getModifiers())) {
                continue;
            }

            List<String> paramNames = getParamNames(ctor);
            api = findConstructorInfo(apiInfoSet, clsName, paramNames);

            if (api == null) {
                pw.println("## Error ## Constructor " + clsName + formatParams(paramNames)
                        + " is not found in the API signature data.");
                errCount++;
                continue;
            }

            compareDeprecated(isAPIDeprecated(api), ctor.isAnnotationPresent(Deprecated.class), clsName,
                    api.getClassName() + formatParams(paramNames), "Constructor");
        }

        // check methods
        for (Method mtd : cls.getDeclaredMethods()) {
            // Note: We exclude synthetic method.
            if (!isPublicOrProtected(mtd.getModifiers()) || mtd.isSynthetic()) {
                continue;
            }

            String mtdName = mtd.getName();
            List<String> paramNames = getParamNames(mtd);
            api = findMethodInfo(apiInfoSet, clsName, mtdName, paramNames);

            if (api == null) {
                pw.println("## Error ## Method " + clsName + "#" + mtdName + formatParams(paramNames)
                        + " is not found in the API signature data.");
                errCount++;
                continue;
            }

            compareDeprecated(isAPIDeprecated(api), mtd.isAnnotationPresent(Deprecated.class), clsName, mtdName
                    + formatParams(paramNames), "Method");

        }
    }

    private void checkEnum(Class<?> cls, Map<String, String> clsNameMap) {
        assert cls.isEnum();

        String enumPath = cls.getName();
        String enumName = clsNameMap.get(enumPath);
        APIInfo api = null;

        if (enumName != null) {
            api = findEnumInfo(apiInfoSet, enumName);
        }
        if (api == null) {
            pw.println("## Error ## Enum " + enumName + " is not found in the API signature data.");
            errCount++;
        }

        // check enum
        compareDeprecated(isAPIDeprecated(api), cls.isAnnotationPresent(Deprecated.class), enumName, null, "Enum");

        // check enum constants
        for (Field ec : cls.getDeclaredFields()) {
            if (!ec.isEnumConstant()) {
                continue;
            }
            String ecName = ec.getName();
            api = findEnumConstantInfo(apiInfoSet, enumName, ecName);
            if (api == null) {
                pw.println("## Error ## Enum constant " + enumName + "." + ecName
                        + " is not found in the API signature data.");
                errCount++;
                continue;
            }

            compareDeprecated(isAPIDeprecated(api), ec.isAnnotationPresent(Deprecated.class), enumName, ecName,
                    "Enum Constant");
        }

        // check methods
        for (Method mtd : cls.getDeclaredMethods()) {
            // Note: We exclude built-in methods in a Java Enum instance
            if (!isPublicOrProtected(mtd.getModifiers()) || isBuiltinEnumMethod(mtd)) {
                continue;
            }

            String mtdName = mtd.getName();
            List<String> paramNames = getParamNames(mtd);
            api = findMethodInfo(apiInfoSet, enumName, mtdName, paramNames);

            if (api == null) {
                pw.println("## Error ## Method " + enumName + "#" + mtdName + formatParams(paramNames)
                        + " is not found in the API signature data.");
                errCount++;
                continue;
            }

            compareDeprecated(isAPIDeprecated(api), mtd.isAnnotationPresent(Deprecated.class), enumName, mtdName
                    + formatParams(paramNames), "Method");

        }
    }

    private void compareDeprecated(boolean depTag, boolean depAnt, String cls, String name, String type) {
        if (depTag != depAnt) {
            String apiName = cls;
            if (name != null) {
                apiName += "." + name;
            }
            if (depTag) {
                pw.println("No @Deprecated annotation: [" + type + "] " + apiName);
            } else {
                pw.println("No @deprecated JavaDoc tag: [" + type + "] " + apiName);
            }
            errCount++;
        }
    }

    private static boolean isPublicOrProtected(int modifier) {
        return ((modifier & Modifier.PUBLIC) != 0) || ((modifier & Modifier.PROTECTED) != 0);
    }

    // Check if a method is automatically generated for a each Enum
    private static boolean isBuiltinEnumMethod(Method mtd) {
        // Just check method name for now
        String name = mtd.getName();
        return name.equals("values") || name.equals("valueOf");
    }

    private static boolean isAPIDeprecated(APIInfo api) {
        return api.isDeprecated() || api.isInternal() || api.isObsolete();
    }

    private static APIInfo findClassInfo(Set<APIInfo> apis, String cls) {
        for (APIInfo api : apis) {
            String clsName = api.getPackageName() + "." + api.getName();
            if (api.isClass() && clsName.equals(cls)) {
                return api;
            }
        }
        return null;
    }

    private static APIInfo findFieldInfo(Set<APIInfo> apis, String cls, String field) {
        for (APIInfo api : apis) {
            String clsName = api.getPackageName() + "." + api.getClassName();
            if (api.isField() && clsName.equals(cls) && api.getName().equals(field)) {
                return api;
            }
        }
        return null;
    }

    private static APIInfo findConstructorInfo(Set<APIInfo> apis, String cls, List<String> params) {
        for (APIInfo api : apis) {
            String clsName = api.getPackageName() + "." + api.getClassName();
            if (api.isConstructor() && clsName.equals(cls)) {
                // check params
                List<String> paramsFromApi = getParamNames(api);
                if (paramsFromApi.size() == params.size()) {
                    boolean match = true;
                    for (int i = 0; i < params.size(); i++) {
                        if (!params.get(i).equals(paramsFromApi.get(i))) {
                            match = false;
                            break;
                        }
                    }
                    if (match) {
                        return api;
                    }
                }
            }
        }
        return null;
    }

    private static APIInfo findMethodInfo(Set<APIInfo> apis, String cls, String method, List<String> params) {
        for (APIInfo api : apis) {
            String clsName = api.getPackageName() + "." + api.getClassName();
            if (api.isMethod() && clsName.equals(cls) && api.getName().equals(method)) {
                // check params
                List<String> paramsFromApi = getParamNames(api);
                if (paramsFromApi.size() == params.size()) {
                    boolean match = true;
                    for (int i = 0; i < params.size(); i++) {
                        if (!params.get(i).equals(paramsFromApi.get(i))) {
                            match = false;
                            break;
                        }
                    }
                    if (match) {
                        return api;
                    }
                }
            }
        }
        return null;
    }

    private static APIInfo findEnumInfo(Set<APIInfo> apis, String ecls) {
        for (APIInfo api : apis) {
            String clsName = api.getPackageName() + "." + api.getName();
            if (api.isEnum() && clsName.equals(ecls)) {
                return api;
            }
        }
        return null;
    }

    private static APIInfo findEnumConstantInfo(Set<APIInfo> apis, String ecls, String econst) {
        for (APIInfo api : apis) {
            String clsName = api.getPackageName() + "." + api.getClassName();
            if (api.isEnumConstant() && clsName.equals(ecls) && api.getName().equals(econst)) {
                return api;
            }
        }
        return null;
    }

    private static List<String> getParamNames(APIInfo api) {
        if (!api.isMethod() && !api.isConstructor()) {
            throw new IllegalArgumentException(api.toString() + " is not a constructor or a method.");
        }

        List<String> nameList = new ArrayList<String>();
        String signature = api.getSignature();
        int start = signature.indexOf('(');
        int end = signature.indexOf(')');

        if (start < 0 || end < 0 || start > end) {
            throw new RuntimeException(api.toString() + " has bad API signature: " + signature);
        }

        String paramsSegment = signature.substring(start + 1, end);
        // erase generic args
        if (paramsSegment.indexOf('<') >= 0) {
            StringBuilder buf = new StringBuilder();
            boolean inGenericsParams = false;
            for (int i = 0; i < paramsSegment.length(); i++) {
                char c = paramsSegment.charAt(i);
                if (inGenericsParams) {
                    if (c == '>') {
                        inGenericsParams = false;
                    }
                } else {
                    if (c == '<') {
                        inGenericsParams = true;
                    } else {
                        buf.append(c);
                    }
                }
            }
            paramsSegment = buf.toString();
        }

        if (paramsSegment.length() > 0) {
            String[] params = paramsSegment.split("\\s*,\\s*");
            for (String p : params) {
                if (p.endsWith("...")) {
                    // varargs to array
                    p = p.substring(0, p.length() - 3) + "[]";
                }
                nameList.add(p);
            }
        }

        return nameList;
    }

    private static List<String> getParamNames(Constructor<?> ctor) {
        return toTypeNameList(ctor.getGenericParameterTypes());
    }

    private static List<String> getParamNames(Method method) {
        return toTypeNameList(method.getGenericParameterTypes());
    }

    private static final String[] PRIMITIVES = { "byte", "short", "int", "long", "float", "double", "boolean", "char" };
    private static char[] PRIMITIVE_SIGNATURES = { 'B', 'S', 'I', 'J', 'F', 'D', 'Z', 'C' };

    private static List<String> toTypeNameList(Type[] types) {
        List<String> nameList = new ArrayList<String>();

        for (Type t : types) {
            StringBuilder s = new StringBuilder();
            if (t instanceof ParameterizedType) {
                // throw away generics parameters
                ParameterizedType prdType = (ParameterizedType) t;
                Class<?> rawType = (Class<?>) prdType.getRawType();
                s.append(rawType.getCanonicalName());
            } else if (t instanceof WildcardType) {
                // we don't need to worry about WildcardType,
                // because this tool erases generics parameters
                // for comparing method/constructor parameters
                throw new RuntimeException("WildcardType not supported by this tool");
            } else if (t instanceof TypeVariable) {
                // this tool does not try to resolve actual parameter
                // type - for example, "<T extends Object> void foo(T in)"
                // this tool just use the type variable "T" for API signature
                // comparison. This is actually not perfect, but should be
                // sufficient for our purpose.
                TypeVariable<?> tVar = (TypeVariable<?>) t;
                s.append(tVar.getName());
            } else if (t instanceof GenericArrayType) {
                // same as TypeVariable. "T[]" is sufficient enough.
                GenericArrayType tGenArray = (GenericArrayType) t;
                s.append(tGenArray.toString());
            } else if (t instanceof Class) {
                Class<?> tClass = (Class<?>) t;
                String tName = tClass.getCanonicalName();

                if (tName.charAt(0) == '[') {
                    // Array type
                    int idx = 0;
                    for (; idx < tName.length(); idx++) {
                        if (tName.charAt(idx) != '[') {
                            break;
                        }
                    }
                    int dimension = idx;
                    char sigChar = tName.charAt(dimension);

                    String elemType = null;
                    if (sigChar == 'L') {
                        // class
                        elemType = tName.substring(dimension + 1, tName.length() - 1);
                    } else {
                        // primitive
                        for (int i = 0; i < PRIMITIVE_SIGNATURES.length; i++) {
                            if (sigChar == PRIMITIVE_SIGNATURES[i]) {
                                elemType = PRIMITIVES[i];
                                break;
                            }
                        }
                    }

                    if (elemType == null) {
                        throw new RuntimeException("Unexpected array type: " + tName);
                    }

                    s.append(elemType);
                    for (int i = 0; i < dimension; i++) {
                        s.append("[]");
                    }
                } else {
                    s.append(tName);
                }
            } else {
                throw new IllegalArgumentException("Unknown type: " + t);
            }

            nameList.add(s.toString());
        }

        return nameList;
    }

    private static String formatParams(List<String> paramNames) {
        StringBuilder buf = new StringBuilder("(");
        boolean isFirst = true;
        for (String p : paramNames) {
            if (isFirst) {
                isFirst = false;
            } else {
                buf.append(", ");
            }
            buf.append(p);
        }
        buf.append(")");

        return buf.toString();
    }
}
