/*
 * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.io;

import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

import static jdk.internal.event.SerializationMisdeclarationEvent.*;
import static java.lang.reflect.Modifier.*;

final class SerializationMisdeclarationChecker {

    private static final String SUID_NAME = "serialVersionUID";
    private static final String SERIAL_PERSISTENT_FIELDS_NAME = "serialPersistentFields";
    private static final String WRITE_OBJECT_NAME = "writeObject";
    private static final String READ_OBJECT_NAME = "readObject";
    private static final String READ_OBJECT_NO_DATA_NAME = "readObjectNoData";
    private static final String WRITE_REPLACE_NAME = "writeReplace";
    private static final String READ_RESOLVE_NAME = "readResolve";

    private static final Class<?>[] WRITE_OBJECT_PARAM_TYPES = {ObjectOutputStream.class};
    private static final Class<?>[] READ_OBJECT_PARAM_TYPES = {ObjectInputStream.class};

    /*
     * The sharing of a single Class<?>[] instance here is just to avoid wasting
     * space, and should not be considered as a conceptual sharing of types.
     */
    private static final Class<?>[] READ_OBJECT_NO_DATA_PARAM_TYPES = {};
    private static final Class<?>[] WRITE_REPLACE_PARAM_TYPES = READ_OBJECT_NO_DATA_PARAM_TYPES;
    private static final Class<?>[] READ_RESOLVE_PARAM_TYPES = READ_OBJECT_NO_DATA_PARAM_TYPES;

    static void checkMisdeclarations(Class<?> cl) {
        checkSerialVersionUID(cl);
        checkSerialPersistentFields(cl);

        checkPrivateMethod(cl, WRITE_OBJECT_NAME,
                WRITE_OBJECT_PARAM_TYPES, Void.TYPE);
        checkPrivateMethod(cl, READ_OBJECT_NAME,
                READ_OBJECT_PARAM_TYPES, Void.TYPE);
        checkPrivateMethod(cl, READ_OBJECT_NO_DATA_NAME,
                READ_OBJECT_NO_DATA_PARAM_TYPES, Void.TYPE);

        checkAccessibleMethod(cl, WRITE_REPLACE_NAME,
                WRITE_REPLACE_PARAM_TYPES, Object.class);
        checkAccessibleMethod(cl, READ_RESOLVE_NAME,
                READ_RESOLVE_PARAM_TYPES, Object.class);
    }

    private static void checkSerialVersionUID(Class<?> cl) {
        Field f = declaredField(cl, SUID_NAME);
        if (f == null) {
            if (isOrdinaryClass(cl)) {
                commitEvent(cl, SUID_NAME + " should be declared explicitly" +
                        " as a private static final long field");
            }
            return;
        }
        if (cl.isEnum()) {
            commitEvent(cl, SUID_NAME + " should not be declared in an enum class");
        }
        if (!isPrivate(f)) {
            commitEvent(cl, SUID_NAME + " should be private");
        }
        if (!isStatic(f)) {
            commitEvent(cl, SUID_NAME + " must be static");
        }
        if (!isFinal(f)) {
            commitEvent(cl, SUID_NAME + " must be final");
        }
        if (f.getType() != Long.TYPE) {
            commitEvent(cl, SUID_NAME + " must be of type long");
        }
    }

    private static void checkSerialPersistentFields(Class<?> cl) {
        Field f = declaredField(cl, SERIAL_PERSISTENT_FIELDS_NAME);
        if (f == null) {
            return;
        }
        if (cl.isRecord()) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME +
                    " should not be declared in a record class");
        } else if (cl.isEnum()) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME +
                    " should not be declared in an enum class");
        }
        if (!isPrivate(f)) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME + " must be private");
        }
        if (!isStatic(f)) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME + " must be static");
        }
        if (!isFinal(f)) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME + " must be final");
        }
        if (f.getType() != ObjectStreamField[].class) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME +
                    " should be of type ObjectStreamField[]");
        }
        if (!isStatic(f)) {
            return;
        }
        f.setAccessible(true);
        Object spf = objectFromStatic(f);
        if (spf == null) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME + " should be non-null");
            return;
        }
        if (!(spf instanceof ObjectStreamField[])) {
            commitEvent(cl, SERIAL_PERSISTENT_FIELDS_NAME +
                    " must be an instance of ObjectStreamField[]");
        }
    }

    private static void checkPrivateMethod(Class<?> cl,
            String name, Class<?>[] paramTypes, Class<?> retType) {
        for (Method m : cl.getDeclaredMethods()) {
            if (m.getName().equals(name)) {
                checkPrivateMethod(cl, m, paramTypes, retType);
            }
        }
    }

    private static void checkPrivateMethod(Class<?> cl,
            Method m, Class<?>[] paramTypes, Class<?> retType) {
        if (cl.isEnum()) {
            commitEvent(cl, "method " + m + " should not be declared in an enum class");
        } else if (cl.isRecord()) {
            commitEvent(cl, "method " + m + " should not be declared in a record class");
        }
        if (!isPrivate(m)) {
            commitEvent(cl, "method " + m + " must be private");
        }
        if (isStatic(m)) {
            commitEvent(cl, "method " + m + " must be non-static");
        }
        if (m.getReturnType() != retType) {
            commitEvent(cl, "method " + m + " must have return type " + retType);
        }
        if (!Arrays.equals(m.getParameterTypes(), paramTypes)) {
            commitEvent(cl, "method " + m + " must have parameter types " + Arrays.toString(paramTypes));
        }
    }

    private static void checkAccessibleMethod(Class<?> cl,
            String name, Class<?>[] paramTypes, Class<?> retType) {
        for (Class<?> superCl = cl; superCl != null; superCl = superCl.getSuperclass()) {
            for (Method m : superCl.getDeclaredMethods()) {
                if (m.getName().equals(name)) {
                    checkAccessibleMethod(cl, superCl, m, paramTypes, retType);
                }
            }
        }
    }

    private static void checkAccessibleMethod(Class<?> cl,
            Class<?> superCl, Method m, Class<?>[] paramTypes, Class<?> retType) {
        if (superCl.isEnum()) {
            commitEvent(cl, "method " + m + " should not be declared in an enum class");
        }
        if (isAbstract(m)) {
            commitEvent(cl, "method " + m + " must be non-abstract");
        }
        if (isStatic(m)) {
            commitEvent(cl, "method " + m + " must be non-static");
        }
        if (m.getReturnType() != retType) {
            commitEvent(cl, "method " + m + " must have return type " + retType);
        }
        if (!Arrays.equals(m.getParameterTypes(), paramTypes)) {
            commitEvent(cl, "method " + m + " must have parameter types " + Arrays.toString(paramTypes));
        }
        if (isPrivate(m) && cl != superCl
                || isPackageProtected(m) && !isSamePackage(cl, superCl)) {
            commitEvent(cl, "method " + m + " is not accessible");
        }
    }

    private static boolean isSamePackage(Class<?> cl0, Class<?> cl1) {
        return cl0.getClassLoader() == cl1.getClassLoader()
                && cl0.getPackageName().equals(cl1.getPackageName());
    }

    private static boolean isOrdinaryClass(Class<?> cl) {
        /* class Enum and class Record are not considered ordinary classes */
        return !(cl.isRecord() || cl.isEnum() || cl.isArray()
                || Enum.class == cl || Record.class == cl
                || Proxy.isProxyClass(cl));
    }

    private static boolean isPrivate(Member m) {
        return (m.getModifiers() & PRIVATE) != 0;
    }

    private static boolean isPackageProtected(Member m) {
        return (m.getModifiers() & (PRIVATE | PROTECTED | PUBLIC)) == 0;
    }

    private static boolean isAbstract(Member m) {
        return (m.getModifiers() & ABSTRACT) != 0;
    }

    private static boolean isFinal(Member m) {
        return (m.getModifiers() & FINAL) != 0;
    }

    private static boolean isStatic(Member m) {
        return (m.getModifiers() & STATIC) != 0;
    }


    private static Field declaredField(Class<?> cl, String name) {
        try {
            return cl.getDeclaredField(name);
        } catch (NoSuchFieldException ignored) {
        }
        return null;
    }


    private static Object objectFromStatic(Field f) {
        try {
            return f.get(null);
        } catch (IllegalAccessException ignored) {
        }
        return null;
    }

    private static void commitEvent(Class<?> cl, String msg) {
        commit(timestamp(), cl, msg);
    }

}
