#!/usr/bin/env python

import argparse
import json
import sys

r"""
Validates the PEL message registry JSON, which includes checking it against
a JSON schema using the jsonschema module as well as doing some extra checks
that can't be encoded in the schema.
"""


def check_duplicate_names(registry_json):
    r"""
    Check that there aren't any message registry entries with the same
    'Name' field.  There may be a use case for this in the future, but there
    isn't right now.

    registry_json: The message registry JSON
    """

    names = {}
    for entry in registry_json['PELs']:
        if entry['Name'] in names.keys():
            sys.exit("Found multiple uses of error {}".format(entry['Name']))
        else:
            names[entry['Name']] = {}


def check_duplicate_reason_codes(registry_json):
    r"""
    Check that there aren't any message registry entries with the same
    'ReasonCode' field.

    registry_json: The message registry JSON
    """

    reasonCodes = {}
    for entry in registry_json['PELs']:
        if entry['SRC']['ReasonCode'] in reasonCodes.keys():
            sys.exit("Found duplicate SRC reason code {}".format(
                entry['SRC']['ReasonCode']))
        else:
            reasonCodes[entry['SRC']['ReasonCode']] = {}


def check_component_id(registry_json):
    r"""
    Check that the upper byte of the ComponentID field matches the upper byte
    of the ReasonCode field, but not on "11" type SRCs where they aren't
    supposed to match.

    registry_json: The message registry JSON
    """

    for entry in registry_json['PELs']:

        # Don't check on "11" SRCs as those reason codes aren't supposed to
        # match the component ID.
        if entry.get('Type', '') == "11":
            continue

        if 'ComponentID' in entry:
            id = int(entry['ComponentID'], 16)
            reason_code = int(entry['SRC']['ReasonCode'], 16)

            if (id & 0xFF00) != (reason_code & 0xFF00):
                sys.exit("Found mismatching component ID {} vs reason "
                         "code {} for error {}".format(
                             entry['ComponentID'],
                             entry['SRC']['ReasonCode'],
                             entry['Name']))


def check_message_args(registry_json):
    r"""
    Check that if the Message field uses the '%' style placeholders that there
    are that many entries in the MessageArgSources field.  Also checks that
    the MessageArgSources field is present but only if there are placeholders.

    registry_json: The message registry JSON
    """

    for entry in registry_json['PELs']:
        num_placeholders = entry['Documentation']['Message'].count('%')
        if num_placeholders == 0:
            continue

        if 'MessageArgSources' not in entry['Documentation']:
            sys.exit("Missing MessageArgSources property for error {}".
                     format(entry['Name']))

        if num_placeholders != \
                len(entry['Documentation']['MessageArgSources']):
                    sys.exit("Different number of placeholders found in "
                             "Message vs MessageArgSources for error {}".
                             format(entry['Name']))


def validate_schema(registry, schema):
    r"""
    Validates the passed in JSON against the passed in schema JSON

    registry: Path of the file containing the registry JSON
    schema:   Path of the file containing the schema JSON
              Use None to skip the pure schema validation
    """

    with open(registry) as registry_handle:
        registry_json = json.load(registry_handle)

        if schema:

            import jsonschema

            with open(schema) as schema_handle:
                schema_json = json.load(schema_handle)

                try:
                    jsonschema.validate(registry_json, schema_json)
                except jsonschema.ValidationError as e:
                    print(e)
                    sys.exit("Schema validation failed")

        check_duplicate_names(registry_json)

        check_duplicate_reason_codes(registry_json)

        check_component_id(registry_json)

        check_message_args(registry_json)


if __name__ == '__main__':

    parser = argparse.ArgumentParser(
        description='PEL message registry processor')

    parser.add_argument('-v', '--validate', action='store_true',
                        dest='validate',
                        help='Validate the JSON using the schema')

    parser.add_argument('-s', '--schema-file', dest='schema_file',
                        help='The message registry JSON schema file')

    parser.add_argument('-r', '--registry-file', dest='registry_file',
                        help='The message registry JSON file')
    parser.add_argument('-k', '--skip-schema-validation', action='store_true',
                        dest='skip_schema',
                        help='Skip running schema validation. '
                             'Only do the extra checks.')

    args = parser.parse_args()

    if args.validate:
        if not args.schema_file:
            sys.exit("Schema file required")

        if not args.registry_file:
            sys.exit("Registry file required")

        schema = args.schema_file
        if args.skip_schema:
            schema = None

        validate_schema(args.registry_file, schema)
