/*
 * Copyright (c) 2003, 2016, 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.*;
import java.security.ProtectionDomain;
import java.util.*;


/**
 * Simple tests for the TransformerManager
 *
 */
public abstract class
ATransformerManagementTestCase
    extends AInstrumentationTestCase
{
    private static final String redefinedClassName = "DummyClass";

    protected int   kModSamples = 2;
    public final    ClassFileTransformer[] kTransformerSamples = new ClassFileTransformer[]
        {
            new MyClassFileTransformer(         Integer.toString(0)),
            new MyClassFileTransformer( Integer.toString(1)),
            new MyClassFileTransformer(         Integer.toString(2)),
            new MyClassFileTransformer( Integer.toString(3)),
            new MyClassFileTransformer(         Integer.toString(4)),
            new MyClassFileTransformer( Integer.toString(5)),
            new MyClassFileTransformer(         Integer.toString(6)),
            new MyClassFileTransformer( Integer.toString(7)),
            new MyClassFileTransformer(         Integer.toString(8)),
            new MyClassFileTransformer( Integer.toString(9)),
            new MyClassFileTransformer(         Integer.toString(10)),
            new MyClassFileTransformer( Integer.toString(11)),
            new MyClassFileTransformer( Integer.toString(12)),
            new MyClassFileTransformer( Integer.toString(13)),
            new MyClassFileTransformer(         Integer.toString(14)),
            new MyClassFileTransformer( Integer.toString(15)),
            new MyClassFileTransformer(         Integer.toString(16)),
            new MyClassFileTransformer(         Integer.toString(17)),
            new MyClassFileTransformer( Integer.toString(18)),
        };

    private ArrayList           fTransformers;       // The list of transformers
    private int                 fTransformerIndex;   // The number of transformers encountered
    private String              fDelayedFailure;     // Set non-null if failed in transformer


    /**
     * Constructor for ATransformerManagementTestCase.
     */
    public ATransformerManagementTestCase(String name)
    {
        super(name);
    }


    /**
     * Returns one of the sample transformers
     * @return a random transformer
     */
    protected ClassFileTransformer
    getRandomTransformer()
    {
        int randIndex = (int)Math.floor(Math.random() * kTransformerSamples.length);
        verbosePrint("Choosing random transformer #" + randIndex);
        return kTransformerSamples[randIndex];
    }

    /**
     * Method addTransformerToManager.
     * @param manager
     * @param transformer
     */
    protected void
    addTransformerToManager(
        Instrumentation         manager,
        ClassFileTransformer    transformer)
    {
        addTransformerToManager(manager, transformer, false);
    }

    /**
     * Method addTransformerToManager.
     * @param manager
     * @param transformer
     * @param canRetransform
     */
    protected void
    addTransformerToManager(
        Instrumentation         manager,
        ClassFileTransformer    transformer,
        boolean                 canRetransform)
    {
        if (transformer != null)
        {
            fTransformers.add(transformer);
        }
        manager.addTransformer(transformer, canRetransform);
        verbosePrint("Added transformer " + transformer
            + " with canRetransform=" + canRetransform);
    }

    /**
     * Remove transformer from manager and list
     * @param manager
     * @param transformer
     */
    protected void
    removeTransformerFromManager(
        Instrumentation manager,
        ClassFileTransformer transformer)
    {
        assertTrue("Transformer not found in manager ("+transformer+")", manager.removeTransformer(transformer));

        if (transformer != null)
        {
            fTransformers.remove(transformer);
        }
        verbosePrint("Removed transformer " + transformer);
    }

    /**
     * Decrements the transformer index as well as removes transformer
     * @param fInst         manager
     * @param transformer       transformer to remove
     * @param decrementIndex    the tranformer index gets out of sync with transformers
     *                          that are removed from the manager
     */
    protected void
    removeTransformerFromManager(   Instrumentation manager,
                                    ClassFileTransformer transformer,
                                    boolean decrementIndex)
    {
        removeTransformerFromManager(manager, transformer);
        if (decrementIndex)
        {
            fTransformerIndex--;
            verbosePrint("removeTransformerFromManager fTransformerIndex decremented to: " +
                         fTransformerIndex);
        }
    }

    /**
     * verify transformer by asserting that the number of transforms that occured
     * is the same as the number of valid transformers added to the list.
     * @param manager
     */
    protected void
    verifyTransformers(Instrumentation manager)
    {
        File f = new File(System.getProperty("test.classes", "."), redefinedClassName + ".class");
        System.out.println("Reading test class from " + f);
        try
        {
            InputStream redefineStream = new FileInputStream(f);
            byte[] bytes = NamedBuffer.loadBufferFromStream(redefineStream);
            ClassDefinition cd = new ClassDefinition(DummyClass.class, bytes);
            fInst.redefineClasses(new ClassDefinition[]{ cd });
            verbosePrint("verifyTransformers redefined " + redefinedClassName);
        }
        catch (IOException e)
        {
            fail("Could not load the class: " + redefinedClassName);
        }
        catch (ClassNotFoundException e)
        {
            fail("Could not find the class: " + redefinedClassName);
        }
        catch (UnmodifiableClassException e)
        {
            fail("Could not modify the class: " + redefinedClassName);
        }

        // Report any delayed failures
        assertTrue(fDelayedFailure, fDelayedFailure == null);

        assertEquals("The number of transformers that were run does not match the expected number added to manager",
                        fTransformers.size(), fTransformerIndex);
    }


    /**
     * Asserts that the transformer being checked by the manager is the correct
     * one (as far as order goes) and updates the number of transformers that have
     * been called.  Note that since this is being called inside of a transformer,
     * a standard assert (which throws an exception) cannot be used since it would
     * simply cancel the transformation and otherwise be ignored.  Instead, note
     * the failure for delayed processing.
     * @param ClassFileTransformer
     */
    private void
    checkInTransformer(ClassFileTransformer transformer)
    {
        verbosePrint("checkInTransformer: " + transformer);
        if (fDelayedFailure == null)
        {
            if (fTransformers.size() <= fTransformerIndex)
            {
                String msg = "The number of transformers that have checked in (" +(fTransformerIndex+1) +
                    ") is greater number of tranformers created ("+fTransformers.size()+")";
                fDelayedFailure = msg;
                System.err.println("Delayed failure: " + msg);
                verbosePrint("Delayed failure: " + msg);
            }
            if (!fTransformers.get(fTransformerIndex).equals(transformer))
            {
                String msg = "Transformer " + fTransformers.get(fTransformerIndex) +
                    " should be the same as " + transformer;
                fDelayedFailure = msg;
                System.err.println("Delayed failure: " + msg);
                verbosePrint("Delayed failure: " + msg);
            }
            fTransformerIndex++;
            verbosePrint("fTransformerIndex incremented to: " + fTransformerIndex);
        }
    }

    /**
     * Create a new manager, a new transformer list, and initializes the number of transformers
     * indexed to zero.
     */
    protected void
    setUp()
        throws Exception
    {
        super.setUp();
        fTransformers = new ArrayList();
        fTransformerIndex = 0;
        fDelayedFailure = null;
        verbosePrint("setUp completed");
    }

    /**
     * Sets the manager and transformers to null so that setUp needs to update.
     */
    protected void
    tearDown()
        throws Exception
    {
        verbosePrint("tearDown beginning");
        fTransformers = null;
        super.tearDown();
    }

    /*
     *  Simple transformer that registers when it transforms
     */
    public class MyClassFileTransformer extends SimpleIdentityTransformer {
        private final String fID;

        public MyClassFileTransformer(String id) {
            super();
            fID = id;
        }

        public String toString() {
            return MyClassFileTransformer.this.getClass().getName() + fID;
        }

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

            // The transform testing is triggered by redefine, ignore others
            if (classBeingRedefined != null) checkInTransformer(MyClassFileTransformer.this);

            return super.transform(     loader,
                                        className,
                                        classBeingRedefined,
                                        protectionDomain,
                                        classfileBuffer);
        }

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

            // The transform testing is triggered by redefine, ignore others
            if (classBeingRedefined != null) checkInTransformer(MyClassFileTransformer.this);

            return super.transform(     module,
                                        loader,
                                        className,
                                        classBeingRedefined,
                                        protectionDomain,
                                        classfileBuffer);
        }
    }


    /**
     * Class loader that does nothing
     */
    public class MyClassLoader extends ClassLoader
    {
        /**
         * Constructor for MyClassLoader.
         */
        public MyClassLoader()
        {
            super();
        }

    }

    public String debug_byteArrayToString(byte[] b) {
        if (b == null) return "null";

        StringBuffer buf = new StringBuffer();
        buf.append("byte[");
        buf.append(b.length);
        buf.append("] (");
        for (int i = 0; i < b.length; i++)
        {
            buf.append(b[i]);
            buf.append(",");
        }
        buf.deleteCharAt(buf.length()-1);
        buf.append(")");

        return buf.toString();
    }
}
