/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.netbeans.modules.debugger.jpda.truffle;

import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.InvocationException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.StringReference;
import com.sun.jdi.VirtualMachine;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import org.netbeans.modules.debugger.jpda.jdi.InternalExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.ObjectCollectedExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.ObjectReferenceWrapper;
import org.netbeans.modules.debugger.jpda.jdi.UnsupportedOperationExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.VMDisconnectedExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.VirtualMachineWrapper;

/**
 * Create values with disabled collection, which can be released later on.
 * This is necessary e.g. for temporary variables so that they are not collected
 * prematurely.
 */
public final class PersistentValues {

    private final VirtualMachine vm;
    private final List<ObjectReference> references = new ArrayList<>(5);

    public PersistentValues(VirtualMachine vm) {
        this.vm = vm;
    }

    public StringReference mirrorOf(String string) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper {
        StringReference stringMirror = null;
        while (stringMirror == null) {
            stringMirror = VirtualMachineWrapper.mirrorOf(vm, string);
            try {
                ObjectReferenceWrapper.disableCollection(stringMirror);
            } catch (ObjectCollectedExceptionWrapper ce) {
                stringMirror = null;
            }
        }
        references.add(stringMirror);
        return stringMirror;
    }

    /**
     * @return the reference or <code>null</code> in case of JDI exceptions.
     */
    public StringReference mirrorOf0(String string) {
        try {
            return mirrorOf(string);
        } catch (InternalExceptionWrapper | UnsupportedOperationExceptionWrapper | VMDisconnectedExceptionWrapper e) {
            return null;
        }
    }

    public <T extends ObjectReference> T valueOf(ValueSupplier<T> valueSupplier) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper {
        T value = null;
        while (value == null) {
            value = valueSupplier.get();
            try {
                ObjectReferenceWrapper.disableCollection(value);
            } catch (ObjectCollectedExceptionWrapper ce) {
                value = null;
            }
        }
        references.add(value);
        return value;
    }

    public <T extends ObjectReference> T invokeOf(InvokeSupplier<T> valueSupplier) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException, InvocationException, ObjectCollectedExceptionWrapper {
        T value = null;
        while (value == null) {
            value = valueSupplier.get();
            try {
                ObjectReferenceWrapper.disableCollection(value);
            } catch (ObjectCollectedExceptionWrapper ce) {
                value = null;
            }
        }
        references.add(value);
        return value;
    }

    public void collect() {
        for (ObjectReference reference : references) {
            try {
                ObjectReferenceWrapper.enableCollection(reference);
            } catch (InternalExceptionWrapper | ObjectCollectedExceptionWrapper | UnsupportedOperationExceptionWrapper ex) {
                // continue
            } catch (VMDisconnectedExceptionWrapper ex) {
                break;
            }
        }
        references.clear();
    }

    @FunctionalInterface
    public interface ValueSupplier<T> {

        public T get() throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper;
    }

    @FunctionalInterface
    public interface InvokeSupplier<T> {

        public T get() throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException, InvocationException, ObjectCollectedExceptionWrapper;
    }
}
