/*
 * Copyright (c) 1998, 2008, 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 com.sun.tools.jdi;

import com.sun.jdi.*;

import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Collections;

public class StackFrameImpl extends MirrorImpl
                            implements StackFrame, ThreadListener
{
    /* Once false, frame should not be used.
     * access synchronized on (vm.state())
     */
    private boolean isValid = true;

    private final ThreadReferenceImpl thread;
    private final long id;
    private final Location location;
    private Map<String, LocalVariable> visibleVariables =  null;
    private ObjectReference thisObject = null;

    StackFrameImpl(VirtualMachine vm, ThreadReferenceImpl thread,
                   long id, Location location) {
        super(vm);
        this.thread = thread;
        this.id = id;
        this.location = location;
        thread.addListener(this);
    }

    /*
     * ThreadListener implementation
     * Must be synchronized since we must protect against
     * sending defunct (isValid == false) stack ids to the back-end.
     */
    public boolean threadResumable(ThreadAction action) {
        synchronized (vm.state()) {
            if (isValid) {
                isValid = false;
                return false;   /* remove this stack frame as a listener */
            } else {
                throw new InternalException(
                                  "Invalid stack frame thread listener");
            }
        }
    }

    void validateStackFrame() {
        if (!isValid) {
            throw new InvalidStackFrameException("Thread has been resumed");
        }
    }

    /**
     * Return the frame location.
     * Need not be synchronized since it cannot be provably stale.
     */
    public Location location() {
        validateStackFrame();
        return location;
    }

    /**
     * Return the thread holding the frame.
     * Need not be synchronized since it cannot be provably stale.
     */
    public ThreadReference thread() {
        validateStackFrame();
        return thread;
    }

    public boolean equals(Object obj) {
        if ((obj != null) && (obj instanceof StackFrameImpl)) {
            StackFrameImpl other = (StackFrameImpl)obj;
            return (id == other.id) &&
                   (thread().equals(other.thread())) &&
                   (location().equals(other.location())) &&
                    super.equals(obj);
        } else {
            return false;
        }
    }

    public int hashCode() {
        return (thread().hashCode() << 4) + ((int)id);
    }

    public ObjectReference thisObject() {
        validateStackFrame();
        MethodImpl currentMethod = (MethodImpl)location.method();
        if (currentMethod.isStatic() || currentMethod.isNative()) {
            return null;
        } else {
            if (thisObject == null) {
                PacketStream ps;

                /* protect against defunct frame id */
                synchronized (vm.state()) {
                    validateStackFrame();
                    ps = JDWP.StackFrame.ThisObject.
                                      enqueueCommand(vm, thread, id);
                }

                /* actually get it, now that order is guaranteed */
                try {
                    thisObject = JDWP.StackFrame.ThisObject.
                                      waitForReply(vm, ps).objectThis;
                } catch (JDWPException exc) {
                    switch (exc.errorCode()) {
                    case JDWP.Error.INVALID_FRAMEID:
                    case JDWP.Error.THREAD_NOT_SUSPENDED:
                    case JDWP.Error.INVALID_THREAD:
                        throw new InvalidStackFrameException();
                    default:
                        throw exc.toJDIException();
                    }
                }
            }
        }
        return thisObject;
    }

    /**
     * Build the visible variable map.
     * Need not be synchronized since it cannot be provably stale.
     */
    private void createVisibleVariables() throws AbsentInformationException {
        if (visibleVariables == null) {
            List<LocalVariable> allVariables = location.method().variables();
            Map<String, LocalVariable> map = new HashMap<String, LocalVariable>(allVariables.size());

            for (LocalVariable variable : allVariables) {
                String name = variable.name();
                if (variable.isVisible(this)) {
                    LocalVariable existing = map.get(name);
                    if ((existing == null) ||
                        ((LocalVariableImpl)variable).hides(existing)) {
                        map.put(name, variable);
                    }
                }
            }
            visibleVariables = map;
        }
    }

    /**
     * Return the list of visible variable in the frame.
     * Need not be synchronized since it cannot be provably stale.
     */
    public List<LocalVariable> visibleVariables() throws AbsentInformationException {
        validateStackFrame();
        createVisibleVariables();
        List<LocalVariable> mapAsList = new ArrayList<LocalVariable>(visibleVariables.values());
        Collections.sort(mapAsList);
        return mapAsList;
    }

    /**
     * Return a particular variable in the frame.
     * Need not be synchronized since it cannot be provably stale.
     */
    public LocalVariable visibleVariableByName(String name) throws AbsentInformationException  {
        validateStackFrame();
        createVisibleVariables();
        return visibleVariables.get(name);
    }

    public Value getValue(LocalVariable variable) {
        List<LocalVariable> list = new ArrayList<LocalVariable>(1);
        list.add(variable);
        return getValues(list).get(variable);
    }

    public Map<LocalVariable, Value> getValues(List<? extends LocalVariable> variables) {
        validateStackFrame();
        validateMirrors(variables);

        int count = variables.size();
        JDWP.StackFrame.GetValues.SlotInfo[] slots =
                           new JDWP.StackFrame.GetValues.SlotInfo[count];

        for (int i=0; i<count; ++i) {
            LocalVariableImpl variable = (LocalVariableImpl)variables.get(i);
            if (!variable.isVisible(this)) {
                throw new IllegalArgumentException(variable.name() +
                                 " is not valid at this frame location");
            }
            slots[i] = new JDWP.StackFrame.GetValues.SlotInfo(variable.slot(),
                                      (byte)variable.signature().charAt(0));
        }

        PacketStream ps;

        /* protect against defunct frame id */
        synchronized (vm.state()) {
            validateStackFrame();
            ps = JDWP.StackFrame.GetValues.enqueueCommand(vm, thread, id, slots);
        }

        /* actually get it, now that order is guaranteed */
        ValueImpl[] values;
        try {
            values = JDWP.StackFrame.GetValues.waitForReply(vm, ps).values;
        } catch (JDWPException exc) {
            switch (exc.errorCode()) {
                case JDWP.Error.INVALID_FRAMEID:
                case JDWP.Error.THREAD_NOT_SUSPENDED:
                case JDWP.Error.INVALID_THREAD:
                    throw new InvalidStackFrameException();
                default:
                    throw exc.toJDIException();
            }
        }

        if (count != values.length) {
            throw new InternalException(
                      "Wrong number of values returned from target VM");
        }
        Map<LocalVariable, Value> map = new HashMap<LocalVariable, Value>(count);
        for (int i=0; i<count; ++i) {
            LocalVariableImpl variable = (LocalVariableImpl)variables.get(i);
            map.put(variable, values[i]);
        }
        return map;
    }

    public void setValue(LocalVariable variableIntf, Value valueIntf)
        throws InvalidTypeException, ClassNotLoadedException {

        validateStackFrame();
        validateMirror(variableIntf);
        validateMirrorOrNull(valueIntf);

        LocalVariableImpl variable = (LocalVariableImpl)variableIntf;
        ValueImpl value = (ValueImpl)valueIntf;

        if (!variable.isVisible(this)) {
            throw new IllegalArgumentException(variable.name() +
                             " is not valid at this frame location");
        }

        try {
            // Validate and convert value if necessary
            value = ValueImpl.prepareForAssignment(value, variable);

            JDWP.StackFrame.SetValues.SlotInfo[] slotVals =
                new JDWP.StackFrame.SetValues.SlotInfo[1];
            slotVals[0] = new JDWP.StackFrame.SetValues.
                                       SlotInfo(variable.slot(), value);

            PacketStream ps;

            /* protect against defunct frame id */
            synchronized (vm.state()) {
                validateStackFrame();
                ps = JDWP.StackFrame.SetValues.
                                     enqueueCommand(vm, thread, id, slotVals);
            }

            /* actually set it, now that order is guaranteed */
            try {
                JDWP.StackFrame.SetValues.waitForReply(vm, ps);
            } catch (JDWPException exc) {
                switch (exc.errorCode()) {
                case JDWP.Error.INVALID_FRAMEID:
                case JDWP.Error.THREAD_NOT_SUSPENDED:
                case JDWP.Error.INVALID_THREAD:
                    throw new InvalidStackFrameException();
                default:
                    throw exc.toJDIException();
                }
            }
        } catch (ClassNotLoadedException e) {
            /*
             * Since we got this exception,
             * the variable type must be a reference type. The value
             * we're trying to set is null, but if the variable's
             * class has not yet been loaded through the enclosing
             * class loader, then setting to null is essentially a
             * no-op, and we should allow it without an exception.
             */
            if (value != null) {
                throw e;
            }
        }
    }

    public List<Value> getArgumentValues() {
        validateStackFrame();
        MethodImpl mmm = (MethodImpl)location.method();
        List<String> argSigs = mmm.argumentSignatures();
        int count = argSigs.size();
        JDWP.StackFrame.GetValues.SlotInfo[] slots =
                           new JDWP.StackFrame.GetValues.SlotInfo[count];

        int slot;
        if (mmm.isStatic()) {
            slot = 0;
        } else {
            slot = 1;
        }
        for (int ii = 0; ii < count; ++ii) {
            char sigChar = argSigs.get(ii).charAt(0);
            slots[ii] = new JDWP.StackFrame.GetValues.SlotInfo(slot++,(byte)sigChar);
            if (sigChar == 'J' || sigChar == 'D') {
                slot++;
            }
        }

        PacketStream ps;

        /* protect against defunct frame id */
        synchronized (vm.state()) {
            validateStackFrame();
            ps = JDWP.StackFrame.GetValues.enqueueCommand(vm, thread, id, slots);
        }

        ValueImpl[] values;
        try {
            values = JDWP.StackFrame.GetValues.waitForReply(vm, ps).values;
        } catch (JDWPException exc) {
            switch (exc.errorCode()) {
                case JDWP.Error.INVALID_FRAMEID:
                case JDWP.Error.THREAD_NOT_SUSPENDED:
                case JDWP.Error.INVALID_THREAD:
                    throw new InvalidStackFrameException();
                default:
                    throw exc.toJDIException();
            }
        }

        if (count != values.length) {
            throw new InternalException(
                      "Wrong number of values returned from target VM");
        }
        return Arrays.asList((Value[])values);
    }

    void pop() throws IncompatibleThreadStateException {
        validateStackFrame();
        // flush caches and disable caching until command completion
        CommandSender sender =
            new CommandSender() {
                public PacketStream send() {
                    return JDWP.StackFrame.PopFrames.enqueueCommand(vm,
                                 thread, id);
                }
        };
        try {
            PacketStream stream = thread.sendResumingCommand(sender);
            JDWP.StackFrame.PopFrames.waitForReply(vm, stream);
        } catch (JDWPException exc) {
            switch (exc.errorCode()) {
            case JDWP.Error.THREAD_NOT_SUSPENDED:
                throw new IncompatibleThreadStateException(
                         "Thread not current or suspended");
            case JDWP.Error.INVALID_THREAD:   /* zombie */
                throw new IncompatibleThreadStateException("zombie");
            case JDWP.Error.NO_MORE_FRAMES:
                throw new InvalidStackFrameException(
                         "No more frames on the stack");
            default:
                throw exc.toJDIException();
            }
        }

        // enable caching - suspended again
        vm.state().freeze();
    }

    public String toString() {
       return location.toString() + " in thread " + thread.toString();
    }
}
