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

import java.io.*;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.ClassFileTransformer;
import java.net.*;
import java.security.ProtectionDomain;

public class
VerifyLocalVariableTableOnRetransformTest
    extends ATransformerManagementTestCase
{
    private byte[]  fTargetClassBytes;
    private boolean fTargetClassMatches;
    private String  fTargetClassName = "DummyClassWithLVT";
    private boolean fTargetClassSeen;

    /**
     * Constructor for VerifyLocalVariableTableOnRetransformTest.
     * @param name
     */
    public VerifyLocalVariableTableOnRetransformTest(String name)
    {
        super(name);

        String resourceName = fTargetClassName + ".class";
        File f = new File(System.getProperty("test.classes", "."), resourceName);
        System.out.println("Reading test class from " + f);
        try
        {
            InputStream redefineStream = new FileInputStream(f);
            fTargetClassBytes = NamedBuffer.loadBufferFromStream(redefineStream);
            System.out.println("Read " + fTargetClassBytes.length + " bytes.");
        }
        catch (IOException e)
        {
            fail("Could not load the class: "+resourceName);
        }
    }

    public static void
    main (String[] args)
        throws Throwable {
        ATestCaseScaffold   test = new VerifyLocalVariableTableOnRetransformTest(args[0]);
        test.runTest();
    }

    protected final void
    doRunTest()
        throws Throwable {
        verifyClassFileBuffer();
    }

    public void
    verifyClassFileBuffer()
        throws  Throwable
    {
        beVerbose();

        // With this call here, we will see the target class twice:
        // first when it gets loaded and second when it gets retransformed.
        addTransformerToManager(fInst, new MyObserver(), true);

        ClassLoader loader = getClass().getClassLoader();

        Class target = loader.loadClass(fTargetClassName);
        assertEquals(fTargetClassName, target.getName());

        // make an instance to prove the class was really loaded
        Object testInstance = target.newInstance();

        // With this call here, we will see the target class once:
        // when it gets retransformed.
        //addTransformerToManager(fInst, new MyObserver(), true);

        assertTrue(fTargetClassName + " was not seen by transform()",
            fTargetClassSeen);

        // The HotSpot VM hands us class file bytes at initial class
        // load time that match the .class file contents. However,
        // according to the following spec that is not required:
        // https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class...)
        // This test exists to catch any unintentional change in
        // behavior by the HotSpot VM. If this behavior is intentionally
        // changed in the future, then this test will need to be
        // updated.
        assertTrue(fTargetClassName + " did not match .class file",
            fTargetClassMatches);

        fTargetClassSeen = false;
        fTargetClassMatches = false;

        fInst.retransformClasses(target);

        assertTrue(fTargetClassName + " was not seen by transform()",
            fTargetClassSeen);

        // The HotSpot VM doesn't currently preserve the LocalVariable
        // Table (LVT) attribute so the class file bytes seen by the
        // retransformClasses() call will not match the class file bytes
        // seen at initial class load time.
        assertTrue(fTargetClassName + " did not match .class file",
            fTargetClassMatches);
    }

    public class MyObserver implements ClassFileTransformer {
        public MyObserver() {
        }

        public String toString() {
            return MyObserver.this.getClass().getName();
        }

        private void saveMismatchedBytes(byte[] classfileBuffer) {
            try {
                FileOutputStream fos = null;
                // This file will get created in the test execution
                // directory so there is no conflict with the file
                // in the test classes directory.
                String resourceName = fTargetClassName + ".class";
                fos = new FileOutputStream(resourceName);
                fos.write(classfileBuffer);
                fos.close();
            } catch (IOException ex) {
            }
        }

        public byte[]
        transform(
            ClassLoader loader,
            String className,
            Class<?> classBeingRedefined,
            ProtectionDomain    protectionDomain,
            byte[] classfileBuffer) {

            System.out.println(this + ".transform() sees '" + className
                + "' of " + classfileBuffer.length + " bytes.");
            if (className.equals(fTargetClassName)) {
                fTargetClassSeen = true;

                if (classfileBuffer.length != fTargetClassBytes.length) {
                    System.out.println("Warning: " + fTargetClassName
                        + " lengths do not match.");
                    fTargetClassMatches = false;
                    saveMismatchedBytes(classfileBuffer);
                    return null;
                } else {
                    System.out.println("Info: " + fTargetClassName
                        + " lengths match.");
                }

                for (int i = 0; i < classfileBuffer.length; i++) {
                    if (classfileBuffer[i] != fTargetClassBytes[i]) {
                        System.out.println("Warning: " + fTargetClassName
                            + "[" + i + "]: '" + classfileBuffer[i]
                            + "' != '" + fTargetClassBytes[i] + "'");
                        fTargetClassMatches = false;
                        saveMismatchedBytes(classfileBuffer);
                        return null;
                    }
                }

                fTargetClassMatches = true;
                System.out.println("Info: verified '" + fTargetClassName
                    + ".class' matches 'classfileBuffer'.");
            }

            return null;
        }
    }
}
