import contextlib
import os
import pathlib
import subprocess
import sys
import tempfile


@contextlib.contextmanager
def chdir(path):
    cwd = os.getcwd()
    try:
        os.chdir(path)
        yield
    finally:
        os.chdir(cwd)


def prepare_files(files):
    for f in files:
        path = pathlib.Path(f['path'])
        path.parent.mkdir(parents=True, exist_ok=True)
        with open(str(path), 'w') as fh:
            fh.write(f['data'])
        if f.get('executable', False):
            path.chmod(0o755)


@contextlib.contextmanager
def sandbox(files):
    with tempfile.TemporaryDirectory() as tempdir:
        with chdir(tempdir):
            prepare_files(files)
            yield tempdir


def get_oj_exe():
    oj_exe = os.environ.get('TEST_OJ_EXE')
    if oj_exe is not None:
        return [str(pathlib.Path(oj_exe).resolve())]
    else:
        return [sys.executable, '-m', 'onlinejudge._implementation.main']


def run(args, *, env=None, check=False, oj_exe=get_oj_exe()):
    # oj_exe should be evaluated out of sandboxes
    env = env or dict(os.environ)
    env['PYTHONPATH'] = str(pathlib.Path(__file__).parent.parent)  # this is required to run in sandboxes
    return subprocess.run(oj_exe + args, stdout=subprocess.PIPE, stderr=sys.stderr, env=env, check=check)


def run_in_sandbox(args, files):
    with sandbox(files) as tempdir:
        proc = run(args)
        return {
            'proc': proc,
            'tempdir': tempdir,
        }


def cat():
    if os.name == 'nt':
        return '{} -c "import sys; sys.stdout.buffer.write(sys.stdin.buffer.read())"'.format(sys.executable)
    else:
        return 'cat'


def sleep_1sec():
    if os.name == 'nt':
        return '{} -c "import time; time.sleep(1)"'.format(sys.executable)
    else:
        return 'sleep 1.0'


def python_c(cmd):
    assert '"' not in cmd
    return '{} -c "{}"'.format(sys.executable, cmd)


def python_script(path):
    assert '"' not in path
    return '{} "{}"'.format(sys.executable, path)


def is_logged_in(service, memo={}):
    # functools.lru_cache is unusable since Service are unhashable
    url = service.get_url()
    if url not in memo:
        proc = run(['login', '--check', url])
        memo[url] = proc.returncode == 0
    return memo[url]

[((11, 10, 11, 21), 'os.getcwd', 'os.getcwd', ({}, {}), '()', False, 'import os\n'), ((38, 13, 38, 42), 'os.environ.get', 'os.environ.get', ({(38, 28, 38, 41): '"""TEST_OJ_EXE"""'}, {}), "('TEST_OJ_EXE')", False, 'import os\n'), ((49, 11, 49, 105), 'subprocess.run', 'subprocess.run', (), '', False, 'import subprocess\n'), ((13, 8, 13, 22), 'os.chdir', 'os.chdir', ({(13, 17, 13, 21): 'path'}, {}), '(path)', False, 'import os\n'), ((16, 8, 16, 21), 'os.chdir', 'os.chdir', ({(16, 17, 16, 20): 'cwd'}, {}), '(cwd)', False, 'import os\n'), ((21, 15, 21, 38), 'pathlib.Path', 'pathlib.Path', ({(21, 28, 21, 37): "f['path']"}, {}), "(f['path'])", False, 'import pathlib\n'), ((31, 9, 31, 38), 'tempfile.TemporaryDirectory', 'tempfile.TemporaryDirectory', ({}, {}), '()', False, 'import tempfile\n'), ((48, 28, 48, 50), 'pathlib.Path', 'pathlib.Path', ({(48, 41, 48, 49): '__file__'}, {}), '(__file__)', False, 'import pathlib\n'), ((40, 20, 40, 40), 'pathlib.Path', 'pathlib.Path', ({(40, 33, 40, 39): 'oj_exe'}, {}), '(oj_exe)', False, 'import pathlib\n')]