#!/usr/bin/python3
# encoding=utf-8
#
# Copyright © 2015 Simon McVittie <smcv@debian.org>
# SPDX-License-Identifier: GPL-2.0-or-later

import json
import os
import sys

from game_data_packager.util import load_yaml


def main(f: str, out: str) -> None:
    with open(f, encoding='utf-8') as fd:
        data = load_yaml(fd)
    game = os.path.basename(f)[5:].split('.')[0]

    v = data.pop('files', None)
    offload = os.path.splitext(out)[0] + '.files'
    if v is not None:
        with open(offload + '.tmp', 'w', encoding='utf-8') as fd:
            json.dump(v, fd, sort_keys=True)
        os.rename(offload + '.tmp', offload)
    elif os.path.isfile(offload):
        os.remove(offload)

    groups = data.pop('groups', None)
    offload = os.path.splitext(out)[0] + '.groups'

    if groups is not None:
        with open(offload + '.tmp', 'w', encoding='utf-8') as writer:
            writer.write('# Generated file, do not edit.\n')
            writer.write(
                '# Edit %s.yaml and put it next to vfs.zip instead.\n' %
                os.path.basename(game)
            )

            assert isinstance(groups, dict)
            # The group data starts with a list of groups. This is necessary
            # so we can know whether a group member, encountered later on in
            # the data, is a group or a file.
            for group_name, group_data in sorted(groups.items()):
                if isinstance(group_data, dict):
                    if group_data.get('ignorable'):
                        continue

                writer.write('*%s\n' % group_name)

            for group_name, group_data in sorted(groups.items()):
                if isinstance(group_data, dict):
                    if group_data.get('ignorable'):
                        continue

                    writer.write('[%s]\n' % group_name)
                    attrs = {}
                    members = group_data['group_members']
                    for k, v in group_data.items():
                        if k != 'group_members':
                            attrs[k] = v
                    if attrs:
                        json.dump(attrs, writer, sort_keys=True)
                        writer.write('\n')
                elif isinstance(group_data, (str, list)):
                    writer.write('[%s]\n' % group_name)
                    members = group_data
                else:
                    raise AssertionError('group %r should be dict, str or list'
                                         % group_name)

                has_members = False

                if isinstance(members, str):
                    for line in members.splitlines():
                        assert not line.startswith('[')
                        assert not line.startswith('{')
                        line = line.strip()
                        if (line and
                                not line.startswith('#') and
                                not line.startswith('.')):
                            has_members = True
                            parts = line.split()
                            fpath = line.removeprefix(parts[0]).strip()
                            fpath = fpath.removeprefix(parts[1]).strip()
                            line_to_write = \
                                parts[0] + ' ' + parts[1] + ' ' + fpath
                            writer.write(line_to_write)
                            writer.write('\n')
                elif isinstance(members, list):
                    for m in members:
                        has_members = True
                        writer.write('? ? %s\n' % m)
                else:
                    raise AssertionError(('group %r members should be str'
                                         ' or list')
                                         % group_name)

                # an empty group is no use, and would break the assumption
                # that we can use f.group_members to detect groups
                assert has_members

        os.rename(offload + '.tmp', offload)
    elif os.path.isfile(offload):
        os.remove(offload)

    for k in ('sha1sums', 'sha256sums', 'size_and_md5'):
        v = data.pop(k, None)
        offload = os.path.splitext(out)[0] + '.' + k

        if v is not None:
            with open(offload + '.tmp', 'w', encoding='utf-8') as writer:
                writer.write('# Generated file, do not edit.\n')
                writer.write(
                    '# Edit %s.yaml and put it next to vfs.zip instead.\n' %
                    game)

                for line in v.splitlines():
                    stripped = line.strip()
                    if (stripped == '' or
                            stripped.startswith('#') or
                            stripped.startswith('.')):
                        continue
                    writer.write(line)
                    writer.write('\n')
            os.rename(offload + '.tmp', offload)
        elif os.path.isfile(offload):
            os.remove(offload)

    with open(out + '.tmp', 'w', encoding='utf-8') as fd:
        json.dump(data, fd, sort_keys=True)
    os.rename(out + '.tmp', out)


if __name__ == '__main__':
    main(sys.argv[1], sys.argv[2])
