import io
import sys

from telethon import events
from ubb import Ubot


async def aexec(code, event):
    exec(
        (
            'async def __aexec(event): '
            + ''.join(f'\n {l}' for l in code.split('\n'))
        )
    )
    return await locals()['__aexec'](event)
  

@Ubot.on(events.NewMessage(pattern=r'\.eval'))
async def pyrun(event):
    cmd = event.message.message[len('.eval '):]
    me = await Ubot.get_me()
    if event.fwd_from:
        return

    if event.sender_id != me.id:
        return

    if cmd is None:
      return await event.edit('**NO CODE PASSED TO RUN**')
    reply_to_id = event.reply_to_msg_id or event.message.id
    old_stderr = sys.stderr
    old_stdout = sys.stdout
    redirected_output = sys.stdout = io.StringIO()
    redirected_error = sys.stderr = io.StringIO()
    stdout, stderr, exc = None, None, None

    try:
        await aexec(cmd, event)
    except Exception as e:
        exc = e

    stdout = redirected_output.getvalue()
    stderr = redirected_error.getvalue()
    sys.stdout = old_stdout
    sys.stderr = old_stderr

    evaluation = ""
    if exc:
        evaluation = exc
    elif stderr:
        evaluation = stderr
    elif stdout:
        evaluation = stdout
    else:
        evaluation = "Success"

    final_output = f'**EVAL**: `{cmd}`\n\n**OUTPUT**: \n`{evaluation}`'

    if len(final_output) > 4096:
        with io.BytesIO(str.encode(final_output)) as out_file:
            out_file.name = "eval.text"
            await Ubot.send_file(
                event.chat_id,
                out_file,
                force_document=True,
                allow_cache=False,
                caption=cmd,
                reply_to=reply_to_id
            )
            await event.delete()
    else:
        await event.edit(final_output)
