import os
import subprocess
import tempfile

from scripts.test import shared

from . import utils


class AsyncifyTest(utils.BinaryenTestCase):
    def test_asyncify_js(self):
        def test(args):
            print(args)
            shared.run_process(shared.WASM_OPT + args + [self.input_path('asyncify-sleep.wat'), '--asyncify', '-o', 'a.wasm'])
            shared.run_process(shared.WASM_OPT + args + [self.input_path('asyncify-coroutine.wat'), '--asyncify', '-o', 'b.wasm'])
            shared.run_process(shared.WASM_OPT + args + [self.input_path('asyncify-stackOverflow.wat'), '--asyncify', '-o', 'c.wasm'])
            print(f'  file size: {os.path.getsize("a.wasm")}')
            if shared.NODEJS:
                shared.run_process([shared.NODEJS, self.input_path('asyncify.js')], capture_output=True)

        test(['-g'])
        test([])
        test(['-O1'])
        test(['--optimize-level=1'])
        test(['-O3'])
        test(['-Os', '-g'])

    def test_asyncify_pure_wasm(self):
        def test(input_file):
            shared.run_process(shared.WASM_OPT + [input_file, '--asyncify', '-o', 'a.wasm'])
            shared.run_process(shared.WASM_DIS + ['a.wasm', '-o', 'a.wat'])
            output = shared.run_process(shared.WASM_SHELL + ['a.wat'], capture_output=True).stdout
            with open(self.input_path('asyncify-pure.txt')) as f:
                self.assert_equal_ignoring_line_endings(f.read(), output)

        # test wat input
        wat = self.input_path('asyncify-pure.wat')
        test(wat)

        # test wasm input
        shared.run_process(shared.WASM_AS + [wat, '-o', 'a.wasm'])
        test('a.wasm')

    def test_asyncify_list_bad(self):
        for arg, warning in [
            ('--pass-arg=asyncify-removelist@nonexistent', 'nonexistent'),
            ('--pass-arg=asyncify-onlylist@nonexistent', 'nonexistent'),
            ('--pass-arg=asyncify-removelist@main', None),
            ('--pass-arg=asyncify-onlylist@main', None),
            ('--pass-arg=asyncify-removelist@m*n', None),
            ('--pass-arg=asyncify-onlylist@m*n', None),
            ('--pass-arg=asyncify-onlylist@main*', None),
            ('--pass-arg=asyncify-onlylist@*main', None),
            ('--pass-arg=asyncify-removelist@non*existent', 'non*existent'),
            ('--pass-arg=asyncify-onlylist@non*existent', 'non*existent'),
            ('--pass-arg=asyncify-onlylist@DOS_ReadFile(unsigned short, unsigned char*, unsigned short*, bool)', None),
        ]:
            print(arg, warning)
            err = shared.run_process(shared.WASM_OPT + ['-q', self.input_path('asyncify-pure.wat'), '--asyncify', arg], capture_output=True).stderr.strip()
            if warning:
                self.assertIn('warning', err)
                self.assertIn(warning, err)
            else:
                self.assertNotIn('warning', err)

    def test_asyncify_onlylist_and_other(self):
        def test(list_name):
            args = shared.WASM_OPT + [self.input_path('asyncify-pure.wat'),
                                      '--asyncify',
                                      '--pass-arg=asyncify-onlylist@main',
                                      f'--pass-arg=asyncify-{list_name}list@main']
            proc = shared.run_process(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False)
            self.assertNotEqual(proc.returncode, 0, 'must error on using both lists at once')
            self.assertIn('It makes no sense to use both an asyncify only-list together with another list', proc.stdout)

        test('remove')
        test('add')

    def test_asyncify_addlist_and_removelist(self):
        args = shared.WASM_OPT + [self.input_path('asyncify-pure.wat'),
                                  '--asyncify',
                                  '--pass-arg=asyncify-addlist@main',
                                  '--pass-arg=asyncify-removelist@main']
        proc = shared.run_process(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False)
        self.assertNotEqual(proc.returncode, 0, 'must error on using both lists at once')
        self.assertIn('main is found in the add-list and in the remove-list', proc.stdout)

    def test_asyncify_imports(self):
        def test(args):
            return shared.run_process(shared.WASM_OPT + [self.input_path('asyncify-sleep.wat'), '--asyncify', '--print'] + args, stdout=subprocess.PIPE).stdout

        normal = test(['--pass-arg=asyncify-imports@env.sleep'])
        temp = tempfile.NamedTemporaryFile().name
        with open(temp, 'w') as f:
            f.write('env.sleep')
        response = test([f'--pass-arg=asyncify-imports@@{temp}'])
        self.assertEqual(normal, response)
        without = test(['--pass-arg=asyncify-imports@without.anything'])
        self.assertNotEqual(normal, without)

    def test_asyncify_too_many_locals(self):
        # With 64K+ locals we cannot run the liveness analysis optimization, but
        # should at least not fatally error.
        temp = tempfile.NamedTemporaryFile().name
        with open(temp, 'w') as f:
            f.write('(module\n')
            f.write(' (import "env" "foo" (func $import))\n')
            f.write(' (func $many-locals\n')
            for i in range(65 * 1024):
                f.write(f'  (local $x{i} i32)\n')
            f.write('  (call $import)\n')
            f.write(' )\n')
            f.write(')\n')
        shared.run_process(shared.WASM_OPT + [temp, '--asyncify'])
