#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020  The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
"""

This script Reads tag group definition from a file and applies the tag grouping.
First a set of common bits for each group is found (logical OR among all tags
belonging to the group). Then in each tag belonging to the group those bits are
set to 0 but only if they are not already present there.

The resulting data is written into a segbits file.
"""
import argparse
import re
import itertools

from prjxray.util import OpenSafeFile

# =============================================================================


def load_tag_groups(file_name):
    """
    Loads tag groups from a text file.

    A tag group is defined by specifying a space separated list of tags within
    a single line. Lines that are empty or start with '#' are ignored.
    """
    tag_groups = []

    # Load tag group specifications
    with OpenSafeFile(file_name, "r") as fp:
        for line in fp:
            line = line.strip()

            if len(line) == 0 or line.startswith("#"):
                continue

            group = set(line.split())
            if len(group):
                tag_groups.append(group)

    # Check if all tag groups are exclusive
    for tag_group_a, tag_group_b in itertools.combinations(tag_groups, 2):

        tags = tag_group_a & tag_group_b
        if len(tags):
            raise RuntimeError(
                "Tag(s) {} are present in multiple groups".format(
                    " ".join(tags)))

    return tag_groups


# =============================================================================


def parse_bit(bit):
    """
    Decodes string describing a bit. Returns a tuple (frame, bit, value)
    """
    match = re.match("^(!?)([0-9]+)_([0-9]+)$", bit)
    assert match != None, bit

    val = int(match.group(1) != "!")
    frm = int(match.group(2))
    bit = int(match.group(3))

    return frm, bit, val


def bit_to_str(bit):
    """
    Converts a tuple (frame, bit, value) to its string representation.
    """
    s = "!" if not bit[2] else ""
    return "{}{}_{:02d}".format(s, bit[0], bit[1])


def load_segbits(file_name):
    """
    Loads a segbits file.
    """

    segbits = {}

    with OpenSafeFile(file_name, "r") as fp:
        for line in fp:
            line = line.strip()
            fields = line.split()

            if len(fields) < 2:
                raise RuntimeError("Malformed line: '%s'" % line)

            tag = fields[0]

            if "<" in line or ">" in line:
                segbits[tag] = " ".join(fields[1:])

            else:
                bits = set([parse_bit(bit) for bit in fields[1:]])
                segbits[tag] = bits

    return segbits


def save_segbits(file_name, segbits):
    """
    Save segbits to a .db or .rdb file
    """

    with OpenSafeFile(file_name, "w") as fp:
        for tag, bits in segbits.items():

            if isinstance(bits, str):
                line = tag + " " + bits

            elif isinstance(bits, set):
                line = tag + " "
                line += " ".join(
                    [bit_to_str(bit) for bit in sorted(list(bits))])

            fp.write(line + "\n")


# =============================================================================


def mask_out_bits(segbits, mask, tags_to_mask=None):
    """
    Given a set of bits and a list of tags to affect (optional) removes all
    the bits from each tag that are present (and equal) in the masking set.
    """

    if tags_to_mask is None:
        tags_to_mask = segbits.keys()

    # Mask out matching bits
    for tag in tags_to_mask:
        bits = segbits[tag]

        bits = set(bits) - set(mask)
        segbits[tag] = bits

    return segbits


def find_common_bits_for_tag_groups(segbits, tag_groups):
    """
    For each tag group finds a common set of bits that have value of one.
    """

    bit_groups = []

    for tag_group in tag_groups:
        bit_group = set()

        for tag, bits in segbits.items():
            if tag in tag_group and isinstance(bits, set):
                ones = set([b for b in bits if b[2]])
                bit_group |= ones

        bit_groups.append(bit_group)

    return bit_groups


def group_tags(segbits, tag_groups, bit_groups):
    """
    Implements tag grouping. If a tag belongs to a group then the common bits
    of that group are added to is as zeros.
    """

    for tag_group, bit_group in zip(tag_groups, bit_groups):
        zeros = set([(b[0], b[1], 0) for b in bit_group])
        for tag in tag_group:

            # Insert zero bits
            if tag in segbits.keys():
                bits = segbits[tag]

                if not isinstance(bits, set):
                    bits = set()
                    segbits[tag] = bits

                for z in zeros:
                    if not (z[0], z[1], 1) in bits:
                        bits.add(z)

    return segbits


# =============================================================================


def main():

    # Parse arguments
    parser = argparse.ArgumentParser()

    parser.add_argument("-i", required=True, type=str, help="Input .rdb file")
    parser.add_argument(
        "-g", required=True, type=str, help="Input tag group definition file")
    parser.add_argument("-o", required=True, type=str, help="Output .rdb file")

    args = parser.parse_args()

    # Load tag groups
    tag_groups = load_tag_groups(args.g)

    # Load raw database file
    segbits = load_segbits(args.i)

    # Find common bits
    bit_groups = find_common_bits_for_tag_groups(segbits, tag_groups)
    # Apply tag grouping
    segbits = group_tags(segbits, tag_groups, bit_groups)

    # Save fixed database file
    save_segbits(args.o, segbits)


if __name__ == "__main__":
    main()
