import re

SRC = open('/tmp/opencode/make_runner.py').read()
shim = re.search(r"shim = r'''(.*?)'''", SRC, re.S).group(1)

extra = r'''
__G3N = 0
function __G3(k, v)
  if __G3N < 2000 then
    __G3N = __G3N + 1
    local vt = type(v)
    local vs
    if vt == "string" then vs = string.format("%q", v:sub(1, 60))
    elseif vt == "number" or vt == "boolean" or vt == "nil" then vs = tostring(v)
    elseif vt == "table" then
      local ok, n = pcall(function() local z = 0 for _ in pairs(v) do z = z + 1 end return z end)
      vs = "table#" .. tostring(ok and n or "?")
    else vs = vt end
    __realprint("G3", tostring(k), vt, vs)
  end
end
__PLOGN = 0
function __PLOG(name, k)
  if __PLOGN < 800 then
    __PLOGN = __PLOGN + 1
    __realprint("PROXY", tostring(name), tostring(k))
  end
end
function __V(x)
  local t = type(x)
  if t == "string" then return string.format("%q", x:sub(1, 60)) end
  if t == "number" then return string.format("%.10g", x) end
  if t == "table" then return "tbl#" .. tostring(#x) end
  if t == "function" then return "fn" end
  return t .. ":" .. tostring(x)
end
local function __g(t, k)
  local ok, v = pcall(function() return t[k] end)
  if ok then return v end
  return nil
end
__NINS = {}
local function __nins(O)
  local n = __NINS[O]
  if n then return n end
  local o3 = __g(O, 3)
  if type(o3) == "table" then n = #o3 else n = -1 end
  __NINS[O] = n
  return n
end
__OPN = 0
__OPTOT = {}
__STACK = {}
__SD = 0
__LASTO = nil
__LASTPC = 0
__DUMPED140 = false
function __DUMPPROTO(O, nins)
  __realprint("DUMP", tostring(O), "nins", nins)
  for k = 1, 12 do __realprint("DF", k, __V(__g(O, k))) end
  for _, f in ipairs({7, 8, 9}) do
    local t = __g(O, f)
    if type(t) == "table" then
      local keys = {}
      for kk in pairs(t) do keys[#keys+1] = kk end
      table.sort(keys, function(a, b) return tostring(a) < tostring(b) end)
      __realprint("POOL", f, "n", #keys)
      for i = 1, math.min(#keys, 60) do
        local kk = keys[i]
        __realprint("PV", f, tostring(kk), __V(t[kk]))
      end
    end
  end
end
function __OP(O, pc, z, a, b, c, d, e, f, rt, rd, rc)
  __OPN = __OPN + 1
  __OPTOT[O] = (__OPTOT[O] or 0) + 1
  local ni = __nins(O)
  if O ~= __LASTO then
    if pc == 1 then
      __SD = __SD + 1
      __STACK[__SD] = O
    else
      while __SD > 0 and __STACK[__SD] ~= O do __SD = __SD - 1 end
    end
    if ni == 140 and not __DUMPED140 then
      __DUMPED140 = true
      __DUMPPROTO(O, ni)
    end
    __LASTO = O
  end
  __LASTPC = pc
  if __OPN % 1000000 == 0 then
    local parts = {}
    for i = 1, math.min(__SD, 14) do
      local F = __STACK[i]
      parts[#parts+1] = tostring(__nins(F))
    end
    __realprint("STACK", __OPN, table.concat(parts, ">"), "lastpc", __LASTPC)
  end
end
'''

old = '''    __index = function(self, k)
      if k == "ClassName" then return "Proxy" end'''
new = '''    __index = function(self, k)
      if __PLOG then __PLOG(name, k) end
      if k == "ClassName" then return "Proxy" end'''
shim = shim.replace(old, new, 1)
shim += extra

raw = open('/tmp/opencode/stage2.lua').read()
rhex = re.search(r'__RHEX__\t([0-9a-f]+)', open('/tmp/opencode/cap4.txt').read()).group(1)
rbytes = bytes.fromhex(rhex)
rlit = '"' + ''.join('\\x%02x' % b for b in rbytes) + '"'

s = raw
s = 'local R=buffer.fromstring(' + rlit + ');' + s[len('local R=...;'):]
ret='return h;end;if not T[13084]'
assert s.count(ret)==1
s=s.replace(ret, 'if type(O)=="table" and type(O[3])=="table" and #O[3]==140 then return function() return 0 end end;' + ret, 1)

get = '(q)[d[Q]]=S[p[Q]];'
assert s.count(get) == 1
s = s.replace(get, '  local __sv=S[p[Q]];__G3(p[Q],__sv);(q)[d[Q]]=__sv;', 1)

head = 'while true do local Z=o[Q];'
assert s.count(head) == 1
s = s.replace(head, 'while true do local Z=o[Q];__OP(O,Q,Z,t[Q],d[Q],P[Q],y[Q],b[Q],p[Q],q[t[Q]],q[d[Q]],q[P[Q]]);', 1)

s = s.replace('return({', 'local __T={', 1)
s = s.rstrip()[:-len('}):A();')] + '};__WRAP(__T);return __T:A();'

profile = r'''
local __CNT = {}
local __CALLS = 0
function __WRAP(T)
  for k, v in pairs(T) do
    if type(v) == "function" then
      __CNT[k] = 0
      T[k] = function(...)
        __CNT[k] = __CNT[k] + 1
        __CALLS = __CALLS + 1
        return v(...)
      end
    end
  end
end
'''

tail = r'''
local __ok,__err = pcall(function()
''' + s + r'''
end)
__realprint("EXEC1", __ok, type(__err))
if __ok then
  local __ok2,__err2 = pcall(__err)
  __realprint("EXEC2", __ok2, tostring(__err2))
  local parts = {}
  for i = 1, math.min(__SD, 20) do parts[#parts+1] = tostring(__nins(__STACK[i])) end
  __realprint("FINALSTACK", table.concat(parts, ">"))
end
'''
out = shim + profile + tail
open('/tmp/opencode/probe8.luau', 'w').write(out)
print("wrote", len(out))
