#!/usr/bin/env python3
#
# Call with pytest. Requires XKB_CONFIG_ROOT to be set

import os
import pytest
import subprocess
import sys
from pathlib import Path


def _xkb_config_root():
    path = os.getenv('XKB_CONFIG_ROOT')
    assert path is not None, 'Environment variable XKB_CONFIG_ROOT must be set'
    print(f'Using {path}')

    xkbpath = Path(path)
    assert (xkbpath / 'symbols').exists(), f'{path} is not an XKB installation'
    return xkbpath


@pytest.fixture
def xkb_config_root():
    return _xkb_config_root()


def pytest_generate_tests(metafunc):
    # for any test_foo function with an argument named xkb_symbols,
    # make it a list of tuples in the form (us, dvorak)
    # The list is generated by scanning all xkb symbol files and extracting the
    # various sections
    if 'xkb_symbols' in metafunc.fixturenames:

        xkb_symbols = []
        # This skips the *_vndr directories, they're harder to test
        for symbols_file in _xkb_config_root().glob('symbols/*'):
            if symbols_file.is_dir():
                continue
            with open(symbols_file) as f:
                print(f'Found file {symbols_file}')
                for line in f:
                    if not line.startswith('xkb_symbols "'):
                        continue
                    section = line.split('"')[1]
                    xkb_symbols.append((symbols_file.name, section))
        assert xkb_symbols
        metafunc.parametrize('xkb_symbols', xkb_symbols)


def test_xkbcomp(xkb_config_root, xkb_symbols):
    layout, variant = xkb_symbols
    keymap = '''
xkb_keymap {
        xkb_keycodes  { include "evdev+aliases(qwerty)" };
        xkb_types     { include "complete"      };
        xkb_compat    { include "complete"      };
        xkb_symbols   { include "pc+%s(%s)"     };
};
''' % (layout, variant)
    print(keymap)

    args = [
        'xkbcomp',
        '-w0',      # reduce warning nose
        '-xkb',
        '-I',       # disable system includes
        f'-I{xkb_config_root}',
        '-', '-',   # from stdin, to stdout
    ]
    p = subprocess.run(args, input=keymap, encoding='utf-8', capture_output=True)
    if p.stderr:
        print(p.stderr, file=sys.stderr)
    if p.returncode != 0:
        print(p.stdout)
    if p.returncode < 0:
        print(f'xkbcomp exited with signal {-p.returncode}', file=sys.stderr)

    assert p.returncode == 0
