# Path: pyjvm/frame.py
# class Frame(object):
#     '''Frame is created for every method invokation'''
# 
#     def __init__(self, _thread, _this_class, _method, _args=[], _desc=""):
#         self.thread = _thread
#         if _thread is not None:
#             self.vm = _thread.vm
#         self.this_class = _this_class
#         self.pc = 0  # Always points to byte code to be executed
#         self.method = _method
#         self.code = _method[2]  # method body (bytecode)
#         self.stack = []
#         self.args = _args
#         self.ret = None  # return value for non void
#         self.has_result = False  # flag if return value is set
#         self.desc = _desc
#         global f_counter
#         self.id = f_counter
#         # to support multithreaded environment
#         self.cpc = 0
#         self.monitor = None
#         f_counter += 1
# 
# Path: pyjvm/thread.py
# class SkipThreadCycle(Exception):
#     '''Thread may skip his execution quota in case when a monitor
#     is busy or sleep was called
#     '''
#     pass
# 
# Path: pyjvm/thread.py
# class Thread(object):
#     '''JMV thread.
#     See threads.txt in documentation for details.
#     '''
# 
#     def __init__(self, _vm, _java_thread):
#         '''Init pyjvm thread
#         _vm reference to current vm
#         _java_thread reference to java's Thread instance in heap
#         '''
#         # One frame per method invocation
#         self.frame_stack = []
#         self.vm = _vm
#         # Support looping for multi-threaded apps
#         self.next_thread = None
#         self.prev_thread = None
#         # Reference to java's Thread instances
#         self.java_thread = _java_thread
#         self.is_alive = False
#         self.waiting_notify = False
#         self.is_notified = False
#         self.monitor_count_cache = 0
#         # For sleep(long) support
#         self.sleep_until = 0
#         if _java_thread is not None:
#             obj = _vm.heap[_java_thread[1]]
#             obj.fields["@pvm_thread"] = self


import time
from pyjvm.frame import Frame
from pyjvm.thread import SkipThreadCycle
from pyjvm.thread import Thread
    '''
    t_ref = args[0]
    o = frame.vm.heap[t_ref[1]]
    run = o.java_class.find_method("run", "()V")
    assert run is not None

    pvm_thread = Thread(frame.vm, t_ref)
    pvm_thread.is_alive = True
    m_args = [None] * run[1]
    m_args[0] = t_ref
    sub = Frame(pvm_thread, o.java_class, run, m_args, "Thread")
    pvm_thread.frame_stack.append(sub)
    frame.vm.add_thread(pvm_thread)


def java_lang_Thread_sleep__J_V(frame, args):
    '''Sleep until certain time'''
    if frame.thread.sleep_until == 0:
        now = int(time.time()) * 1000
        sleepMillis = args[0][1]
        threshold = now + sleepMillis
        frame.thread.sleep_until = threshold
        frame.pc -= 3  # no need !!!!!!!!!!!!!!!!!!!!!!!!!
        frame.stack.append(args[0])
        raise SkipThreadCycle()
    else:
        now = int(time.time()) * 1000
        if frame.thread.sleep_until > now:
            frame.pc -= 3  # no need !!!!!!!!!!!!!!!!!!!!!!!!!
            frame.stack.append(args[0])

# Path: pyjvm/frame.py
# class Frame(object):
#     '''Frame is created for every method invokation'''
# 
#     def __init__(self, _thread, _this_class, _method, _args=[], _desc=""):
#         self.thread = _thread
#         if _thread is not None:
#             self.vm = _thread.vm
#         self.this_class = _this_class
#         self.pc = 0  # Always points to byte code to be executed
#         self.method = _method
#         self.code = _method[2]  # method body (bytecode)
#         self.stack = []
#         self.args = _args
#         self.ret = None  # return value for non void
#         self.has_result = False  # flag if return value is set
#         self.desc = _desc
#         global f_counter
#         self.id = f_counter
#         # to support multithreaded environment
#         self.cpc = 0
#         self.monitor = None
#         f_counter += 1
# 
# Path: pyjvm/thread.py
# class SkipThreadCycle(Exception):
#     '''Thread may skip his execution quota in case when a monitor
#     is busy or sleep was called
#     '''
#     pass
# 
# Path: pyjvm/thread.py
# class Thread(object):
#     '''JMV thread.
#     See threads.txt in documentation for details.
#     '''
# 
#     def __init__(self, _vm, _java_thread):
#         '''Init pyjvm thread
#         _vm reference to current vm
#         _java_thread reference to java's Thread instance in heap
#         '''
#         # One frame per method invocation
#         self.frame_stack = []
#         self.vm = _vm
#         # Support looping for multi-threaded apps
#         self.next_thread = None
#         self.prev_thread = None
#         # Reference to java's Thread instances
#         self.java_thread = _java_thread
#         self.is_alive = False
#         self.waiting_notify = False
#         self.is_notified = False
#         self.monitor_count_cache = 0
#         # For sleep(long) support
#         self.sleep_until = 0
#         if _java_thread is not None:
#             obj = _vm.heap[_java_thread[1]]
#             obj.fields["@pvm_thread"] = self


# Path: pyjvm/platform/java/lang/thread.py
import time
from pyjvm.frame import Frame
from pyjvm.thread import SkipThreadCycle
from pyjvm.thread import Thread

    '''
    t_ref = args[0]
    o = frame.vm.heap[t_ref[1]]
    run = o.java_class.find_method("run", "()V")
    assert run is not None

    pvm_thread = Thread(frame.vm, t_ref)
    pvm_thread.is_alive = True
    m_args = [None] * run[1]
    m_args[0] = t_ref
    sub = Frame(pvm_thread, o.java_class, run, m_args, "Thread")
    pvm_thread.frame_stack.append(sub)
    frame.vm.add_thread(pvm_thread)


def java_lang_Thread_sleep__J_V(frame, args):
    '''Sleep until certain time'''
    if frame.thread.sleep_until == 0:
        now = int(time.time()) * 1000
        sleepMillis = args[0][1]
        threshold = now + sleepMillis
        frame.thread.sleep_until = threshold
        frame.pc -= 3  # no need !!!!!!!!!!!!!!!!!!!!!!!!!
        frame.stack.append(args[0])
        raise SkipThreadCycle()
    else:
        now = int(time.time()) * 1000
        if frame.thread.sleep_until > now:
            frame.pc -= 3  # no need !!!!!!!!!!!!!!!!!!!!!!!!!
            frame.stack.append(args[0])

            raise SkipThreadCycle()