#! /usr/bin/env python3
# -*- mode: Python; -*-


"""
vrt-fix-spaces

Fix space issues in VRT: remove leading and trailing spaces (U+0020)
and collapse multiple consecutive internal spaces into a single space
in structural and positional attribute values of the input VRT.
"""


# TODO:
# - To speed up processing, have options to process only positional or
#   structural attributes, perhaps also choosing which structures to
#   process


import re
import sys

import vrtargsoolib


class SpaceFixer(vrtargsoolib.InputProcessor):
    DESCRIPTION = """
    Fix space issues in input VRT: remove leading and trailing spaces
    and collapse multiple consecutive internal spaces into a single
    space in structural and positional attribute values. Note that the
    tool handles only ASCII space characters (U+0020).
    """
    ARGSPECS = [
        # Only one of --skip-positional-attributes and
        # --skip-structural-attributes is allowed, as having both
        # would make the script run a no-op.
        ('#EXCLUSIVE', [
            ('--skip-positional-attributes -> ! process_pos_attrs',
             'do not fix space issues in positional attributes'),
            ('--skip-structural-attributes -> ! process_struct_attrs',
             'do not fix space issues in structural attribute annotations'),
        ]),
    ]

    def __init__(self):
        super().__init__()

    def main(self, args, inf, ouf):

        LESS_THAN = '<'.encode()[0]
        process_struct_attrs =  args.process_struct_attrs
        process_pos_attrs = args.process_pos_attrs

        def fix_spaces_struct(line):
            """Fix spaces in structural attribute line."""

            def fix_spaces_attr(matchobj):
                """Fix spaces in attribute value in matchobj."""
                val = matchobj.group(1)
                val = val.strip(b' ')
                val = re.sub(rb' {2,}', b' ', val)
                val = b'"' + val + b'"'
                return val

            return re.sub(rb'"([^"]*)"', fix_spaces_attr, line)

        def fix_spaces_token(line):
            """Fix spaces in the positional attributes of line."""
            # It is much faster to handle the whole line than to call
            # fix_spaces_attr for each positional attribute
            line = line[:-1].strip() + b'\n'
            line = re.sub(rb' {2,}', b' ', line)
            line = re.sub(rb'\t +', b'\t', line)
            line = re.sub(rb' +\t', b'\t', line)
            return line

        for line in inf:
            if line[0] == LESS_THAN:
                if process_struct_attrs:
                    line = fix_spaces_struct(line)
            elif process_pos_attrs:
                line = fix_spaces_token(line)
            ouf.write(line)
        ouf.close()


if __name__ == '__main__':
    SpaceFixer().run()
