#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright 2016 EDF R&D
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you may download a copy of license
# from https://www.gnu.org/licenses/gpl-3.0.

"""
Test if any keyword is included into several rules simultaneously.
Useful to check if there are conflicts between rules.

Usage: checkrules rule [rule ...]
"""

from __future__ import unicode_literals

import sys


def main(rules):
    """Main function."""
    from asterstudy.datamodel.catalogs import CATA

    syntax_pkg = CATA.package("Syntax")
    objects_pkg = CATA.package("SyntaxObjects")

    known = ("ExactlyOne", "AtLeastOne", "AtMostOne", "AllTogether",
             "IfFirstAllPresent", "OnlyFirstPresent")

    if not rules:
        sys.exit("Specify rule(s) to check.\n"
                 "Type one or more rules from: {}".format(" ".join(known)))

    rules_to_check = []
    for rule in rules:
        if rule not in known:
            sys.exit("Unknown rule: {}".format(rule))
        rule_cls = getattr(syntax_pkg, rule, None)
        if rule_cls is None:
            sys.exit("Unknown rule: {}".format(rule))
        rules_to_check.append(rule_cls)

    print "---------------------------------------------"
    print "Check conflicts between these rules:\n{}".format(", ".join(rules))
    print "---------------------------------------------"

    def _repr_rule(_rule):
        return "{}: {}".format(_rule.__class__.__name__, _rule.ruleArgs)

    # pragma pylint: disable=protected-access
    for name, command in CATA._catalogs.iteritems():
        if not isinstance(command, objects_pkg.Command):
            continue
        if command.regles is not None:
            rules = [i for i in command.regles
                     if isinstance(i, tuple(rules_to_check))]
            d_cmd = {}
            for rule in rules:
                for arg in rule.ruleArgs:
                    if arg not in d_cmd:
                        d_cmd[arg] = []
                    d_cmd[arg].append(_repr_rule(rule))
            args = [i for i in d_cmd if len(d_cmd[i]) > 1]
            if args:
                print name, ":", args
                for arg in args:
                    print "  ", arg, d_cmd[arg]
                print

if __name__ == "__main__":
    main(sys.argv[1:])
