/*
 * Copyright 2001-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/**
 *  @test
 *  @bug 4287595
 *  @bug 4462989
 *  @bug 4531511
 *  @summary Test class redefinition
 *
 *  @author Robert Field
 *
 *  @library ..
 *  @run build TestScaffold VMConnection TargetListener TargetAdapter
 *  @run compile -g RedefineTest.java
 *  @run shell RedefineSetUp.sh
 *  @run main RedefineTest
 */
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import java.util.*;
import java.io.*;

    /********** target program **********/

class RedefineTarg {
    public static void show(String where){
        System.out.println("Returned: " + where);
    }

    public static void lastly(String where){
    }

    public static void main(String[] args){
        RedefineSubTarg sub = new RedefineSubTarg();
        String where = "";
        for (int i = 0; i < 5; ++i) {
            where = sub.foo(where);
            show(where);
        }
        lastly(where);
    }
}

    /********** test program **********/

public class RedefineTest extends TestScaffold {
    ReferenceType targetClass;
    static final String expected ="Boring Boring Different Boring Different ";
    int repetitionCount = 0;
    boolean beforeRedefine = true;

    RedefineTest (String args[]) {
        super(args);
    }

    public static void main(String[] args)      throws Exception {
        new RedefineTest(args).startTests();
    }

    /********** event handlers **********/

    public void methodEntered(MethodEntryEvent event) {
        Method meth = event.location().method();
        ThreadReference thread = event.thread();

        if (meth.name().equals("foo")) {
            ++repetitionCount;
            beforeRedefine = true;
            try {
                expectNonObsolete(thread);
                inspectLineNumber(event, thread.frame(0));

                doRedefine(thread);
                beforeRedefine = false;

                switch (repetitionCount) {
                case 1:
                case 5:
                    expectNonObsolete(thread);
                    inspectLineNumber(event, thread.frame(0));
                    break;
                case 2:
                case 3:
                case 4:
                    expectObsolete(thread);
                    inspectLineNumber(event, thread.frame(0));
                    break;
                }


            } catch (Exception exc) {
                failure("Test Failure: unexpected exception - " + exc);
                exc.printStackTrace();
            }
        }
    }

    public void breakpointReached(BreakpointEvent event) {
        ThreadReference thread = event.thread();
        try {
            StackFrame frame = thread.frame(0);
            LocalVariable lv = frame.visibleVariableByName("where");
            Value vWhere = frame.getValue(lv);
            String remoteWhere = ((StringReference)vWhere).value();
            println("Value of where: " + remoteWhere);
            if (!remoteWhere.equals(expected)) {
                failure("FAIL: expected result string: '" + expected +
                        "' got: '" + remoteWhere + "'");
            }
        } catch (Exception thr) {
            failure("Test Failure: unexpected exception: " + thr);
        }
    }

    /********** test assists **********/

    void expectNonObsolete(ThreadReference thread) throws Exception {
        if (isObsolete(thread)) {
            failure("FAIL: Method should NOT be obsolete");
        } else {
            println("as it should be, not obsolete");
        }
    }

    void expectObsolete(ThreadReference thread) throws Exception {
        if (isObsolete(thread)) {
            println("obsolete like it should be");
        } else {
            failure("FAIL: Method should be obsolete");
        }
    }

    void inspectLineNumber(LocatableEvent event, StackFrame frame) throws Exception {
        /*
         * For each value of repetitionCount, use the beforeRedefine
         * boolean to distinguish the time before and after the actual
         * redefinition takes place.  Line numbers are inspected both
         * before and after each redefine.
         */
        int n = -1;
        int expectedLine = -1;
        switch (repetitionCount) {
        case 1:
            expectedLine = 4;
            break;
        case 2:
            expectedLine = beforeRedefine ? 4:21;
            break;
        case 3:
            expectedLine = beforeRedefine ? 21:4;
            break;
        case 4:
            expectedLine = beforeRedefine ? 4:21;
            break;
        case 5:
            /* The class won't be redefined on this iteration (look
             * for a java.lang.UnsupportedOperationException instead)
             * so expected line stays the same as last successful
             * redefine.
             */
            expectedLine = 21;
            break;
        }
        Method method = event.location().method();
        if (frame.location().method().isObsolete()) {
            /*
             * Then skip. Obsolete methods are not interesting to
             * inspect.
             */
            println("inspectLineNumber skipping obsolete method " + method.name());
        } else {
            n = method.location().lineNumber();
            int m = frame.location().lineNumber();
            if ((n != expectedLine) || (n != m)) {
                failure("Test Failure: line number disagreement: " +
                        n + " (event) versus " + m + " (frame) versus " + expectedLine +
                        " (expected)");
            } else {
                println("inspectLineNumber in method " + method.name() + " at line " + n);
            }
        }
    }

    boolean isObsolete(ThreadReference thread) throws Exception {
        StackFrame frame = thread.frame(0);
        Method meth = frame.location().method();
        return meth.isObsolete();
    }

    void doRedefine(ThreadReference thread) throws Exception {
        Exception receivedException = null;
        String fileName = "notThis";

        switch (repetitionCount) {
        case 1:
            fileName = "RedefineSubTarg.class";
            break;
        case 2:
            fileName = "Different_RedefineSubTarg.class";
            break;
        case 3:
            fileName = "RedefineSubTarg.class";
            break;
        case 4:
            fileName = "Different_RedefineSubTarg.class";
            break;
        case 5:
            fileName = "SchemaChange_RedefineSubTarg.class";
            break;
        }
        File phyl = new File(fileName);
        byte[] bytes = new byte[(int)phyl.length()];
        InputStream in = new FileInputStream(phyl);
        in.read(bytes);
        in.close();

        Map map = new HashMap();
        map.put(findReferenceType("RedefineSubTarg"), bytes);

        println(System.getProperty("line.separator") + "Iteration # " + repetitionCount +
                " ------ Redefine as: " + fileName);
        try {
            vm().redefineClasses(map);
        } catch (Exception thr) {
            receivedException = thr;
        }
        switch (repetitionCount) {
        case 5:
            if (receivedException == null) {
                failure("FAIL: no exception; expected: UnsupportedOperationException");
            } else if (receivedException instanceof UnsupportedOperationException) {
                println("Received expected exception: " + receivedException);
            } else {
                failure("FAIL: got exception: " + receivedException +
                        ", expected: UnsupportedOperationException");
            }
            break;
        default:
            if (receivedException != null) {
                failure("FAIL: unexpected exception: " +
                        receivedException);
            }
            break;
        }
        return;
    }

    /********** test core **********/

    protected void runTests() throws Exception {

        BreakpointEvent bpe = startToMain("RedefineTarg");
        targetClass = bpe.location().declaringType();
        EventRequestManager erm = vm().eventRequestManager();

        /*
         * Method entry in sub targ
         */
        MethodEntryRequest mee = erm.createMethodEntryRequest();
        mee.addClassFilter("RedefineSubTarg");
        mee.enable();

        /*
         * BP at end to get value
         */
        List lastlys = targetClass.methodsByName("lastly");
        if (lastlys.size() != 1) {
            throw new Exception ("TestFailure: Expected one 'lastly' method, found: " +
                                 lastlys);
        }
        Location loc = ((Method)(lastlys.get(0))).location();
        EventRequest req = erm.createBreakpointRequest(loc);
        req.enable();

        // Allow application to complete and shut down
        listenUntilVMDisconnect();

        /*
         * deal with results of test
         * if anything has called failure("foo") testFailed will be true
         */
        if (!testFailed) {
            println("RedefineTest: passed");
        } else {
            throw new Exception("RedefineTest: failed");
        }
    }
}
