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]

[((144, 155), 'os.getcwd', 'os.getcwd', ([], {}), '()\n', (153, 155), False, 'import os\n'), ((742, 771), 'os.environ.get', 'os.environ.get', (['"""TEST_OJ_EXE"""'], {}), "('TEST_OJ_EXE')\n", (756, 771), False, 'import os\n'), ((1201, 1299), 'subprocess.run', 'subprocess.run', (['(oj_exe + args)'], {'stdout': 'subprocess.PIPE', 'stderr': 'sys.stderr', 'env': 'env', 'check': 'check'}), '(oj_exe + args, stdout=subprocess.PIPE, stderr=sys.stderr,\n    env=env, check=check)\n', (1215, 1299), False, 'import subprocess\n'), ((173, 187), 'os.chdir', 'os.chdir', (['path'], {}), '(path)\n', (181, 187), False, 'import os\n'), ((223, 236), 'os.chdir', 'os.chdir', (['cwd'], {}), '(cwd)\n', (231, 236), False, 'import os\n'), ((300, 323), 'pathlib.Path', 'pathlib.Path', (["f['path']"], {}), "(f['path'])\n", (312, 323), False, 'import pathlib\n'), ((579, 608), 'tempfile.TemporaryDirectory', 'tempfile.TemporaryDirectory', ([], {}), '()\n', (606, 608), False, 'import tempfile\n'), ((1112, 1134), 'pathlib.Path', 'pathlib.Path', (['__file__'], {}), '(__file__)\n', (1124, 1134), False, 'import pathlib\n'), ((819, 839), 'pathlib.Path', 'pathlib.Path', (['oj_exe'], {}), '(oj_exe)\n', (831, 839), False, 'import pathlib\n')]