/*
 * Copyright (c) 2013, 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.
 *
 * 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.
 */

/*
 * @test
 * @bug 8023668
 * @summary Desugar serializable lambda bodies using more robust naming scheme
 * @library /tools/javac/lib
 * @build ToolBox
 * @run main TestSerializedLambdaNameStability
 */

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.*;

public class TestSerializedLambdaNameStability {

    final ClassLoader writingClassLoader;
    final ClassLoader clonedClassLoader;
    final ClassLoader checkingClassLoader;

    TestSerializedLambdaNameStability()  {
        writingClassLoader = new TestClassLoader("before");
        clonedClassLoader = new TestClassLoader("before");
        checkingClassLoader = new TestClassLoader("after");
    }

    public static void main(String... args) throws Exception {
        new TestSerializedLambdaNameStability().doit("NameOfCapturedArgs", true);
        new TestSerializedLambdaNameStability().doit("TypesOfCapturedArgs", true);
        new TestSerializedLambdaNameStability().doit("OrderOfCapturedArgs", true);
        new TestSerializedLambdaNameStability().doit("VariableAssignmentTarget", false);
        new TestSerializedLambdaNameStability().doit("TargetName", true);
        new TestSerializedLambdaNameStability().doit("TargetType", true);
    }

    public void doit(String name, boolean expectFail) throws Exception {
        String iName = "I" + name;
        String testName = "TEST" + name;
        Class<?> kw = writingClassLoader.loadClass(testName);
        Object instw = getInstance(kw);
        Method mw = getMethod(kw, "write", ObjectOutput.class);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (ObjectOutput out = new ObjectOutputStream(baos)) {
            mw.invoke(instw, out);
        }
        byte[] ser = baos.toByteArray();

        // Read and check clone
        readCheck(iName, testName, clonedClassLoader, ser);
        System.err.printf("cloned test readCheck %s\n", testName);

        // Read and check other
        if (expectFail) {
            try {
                readCheck(iName, testName, checkingClassLoader, ser);
            } catch (InvocationTargetException ite) {
                Throwable underlying = ite;
                while (underlying != null && !(underlying instanceof IllegalArgumentException)) {
                    underlying = underlying.getCause();
                }
                if (underlying != null) {
                    if (underlying.getMessage().contains("deserialization")) {
                        System.err.printf("PASS: other test %s got expected exception %s\n", testName, underlying);
                        return;
                    }
                }
                System.err.printf("FAIL: other test %s got unexpected exception %s\n", testName, ite);
                throw new Exception("unexpected exception ", ite);
            }
            System.err.printf("FAIL: other test %s expected an exception", testName);
            throw new Exception("expected an exception" + testName);
        } else {
            readCheck(iName, testName, checkingClassLoader, ser);
            System.err.printf("PASS: other test %s readCheck\n", testName);
        }
    }

    void readCheck(String iName, String testName, ClassLoader loader, byte[] ser) throws Exception {
        Class<?> k = loader.loadClass(testName);
        Object inst = getInstance(k);
        Method mrc = getMethod(k, "readCheck", ObjectInput.class);
        ByteArrayInputStream bais = new ByteArrayInputStream(ser);
        try (ObjectInput in = new ObjectInputStream(bais)) {
            mrc.invoke(inst, in);
        }
    }

    Method getMethod(Class<?> k, String name, Class<?> argTypes) throws Exception {
        Method meth = k.getDeclaredMethod(name, argTypes);
        meth.setAccessible(true);
        return meth;
    }

    Object getInstance(Class<?> k) throws Exception {
        Constructor<?> cons = k.getConstructors()[0];
        cons.setAccessible(true);
        return cons.newInstance();
    }

    static class TestClassLoader extends ClassLoader  {
        static final String compiledDir = System.getProperty("user.dir");
        static final String sourceBaseDir = System.getProperty("test.src");

        final String context;

        public TestClassLoader(String context) {
            super();
            this.context = context;
        }

        @Override
        public Class findClass(String name) throws ClassNotFoundException {
            byte[] b;

            try {
                b = loadClassData(name);
            } catch (Throwable th) {
                // th.printStackTrace();
                throw new ClassNotFoundException("Loading error", th);
            }
            return defineClass(name, b, 0, b.length);
        }

        private byte[] loadClassData(String name) throws Exception {
            String srcName;
            if (name.startsWith("TEST"))
                srcName = name;
            else if (name.startsWith("I"))
                srcName = "TEST" + name.substring(1);
            else
                throw new Exception("Did not expect to load " + name);
            Path srcFile = Paths.get(sourceBaseDir, context, srcName + ".java");
            String testSource = new String(Files.readAllBytes(srcFile));
            ToolBox.JavaToolArgs javacSuccessArgs =
                    new ToolBox.JavaToolArgs().setSources(testSource);
            ToolBox.javac(javacSuccessArgs);
            Path cfFile = Paths.get(compiledDir, name + ".class");
            byte[] bytes = Files.readAllBytes(cfFile);
            return bytes;
        }
    }
}
