# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

import argparse
import codecs
import copy
import logging
import json
import os

from collections import OrderedDict
from xml.dom.minidom import parse, parseString, Element


class VSFlags:
    """Flags corresponding to cmIDEFlagTable."""
    UserValue = "UserValue"  # (1 << 0)
    UserIgnored = "UserIgnored"  # (1 << 1)
    UserRequired = "UserRequired"  # (1 << 2)
    Continue = "Continue"  #(1 << 3)
    SemicolonAppendable = "SemicolonAppendable"  # (1 << 4)
    UserFollowing = "UserFollowing"  # (1 << 5)
    CaseInsensitive = "CaseInsensitive"  # (1 << 6)
    UserValueIgnored = [UserValue, UserIgnored]
    UserValueRequired = [UserValue, UserRequired]


def vsflags(*args):
    """Combines the flags."""
    values = []

    for arg in args:
        __append_list(values, arg)

    return values


def read_msbuild_xml(path, values=None):
    """Reads the MS Build XML file at the path and returns its contents.

    Keyword arguments:
    values -- The map to append the contents to (default {})
    """
    if values is None:
        values = {}

    # Attempt to read the file contents
    try:
        document = parse(path)
    except Exception as e:
        logging.exception('Could not read MS Build XML file at %s', path)
        return values

    # Convert the XML to JSON format
    logging.info('Processing MS Build XML file at %s', path)

    # Get the rule node
    rule = document.getElementsByTagName('Rule')[0]

    rule_name = rule.attributes['Name'].value

    logging.info('Found rules for %s', rule_name)

    # Proprocess Argument values
    __preprocess_arguments(rule)

    # Get all the values
    converted_values = []
    __convert(rule, 'EnumProperty', converted_values, __convert_enum)
    __convert(rule, 'BoolProperty', converted_values, __convert_bool)
    __convert(rule, 'StringListProperty', converted_values,
              __convert_string_list)
    __convert(rule, 'StringProperty', converted_values, __convert_string)
    __convert(rule, 'IntProperty', converted_values, __convert_string)

    values[rule_name] = converted_values

    return values


def read_msbuild_json(path, values=None):
    """Reads the MS Build JSON file at the path and returns its contents.

    Keyword arguments:
    values -- The list to append the contents to (default [])
    """
    if values is None:
        values = []

    if not os.path.exists(path):
        logging.info('Could not find MS Build JSON file at %s', path)
        return values

    try:
        values.extend(__read_json_file(path))
    except Exception as e:
        logging.exception('Could not read MS Build JSON file at %s', path)
        return values

    logging.info('Processing MS Build JSON file at %s', path)

    return values

def main():
    """Script entrypoint."""
    # Parse the arguments
    parser = argparse.ArgumentParser(
        description='Convert MSBuild XML to JSON format')

    parser.add_argument(
        '-t', '--toolchain', help='The name of the toolchain', required=True)
    parser.add_argument(
        '-o', '--output', help='The output directory', default='')
    parser.add_argument(
        '-r',
        '--overwrite',
        help='Whether previously output should be overwritten',
        dest='overwrite',
        action='store_true')
    parser.set_defaults(overwrite=False)
    parser.add_argument(
        '-d',
        '--debug',
        help="Debug tool output",
        action="store_const",
        dest="loglevel",
        const=logging.DEBUG,
        default=logging.WARNING)
    parser.add_argument(
        '-v',
        '--verbose',
        help="Verbose output",
        action="store_const",
        dest="loglevel",
        const=logging.INFO)
    parser.add_argument('input', help='The input files', nargs='+')

    args = parser.parse_args()

    toolchain = args.toolchain

    logging.basicConfig(level=args.loglevel)
    logging.info('Creating %s toolchain files', toolchain)

    values = {}

    # Iterate through the inputs
    for input in args.input:
        input = __get_path(input)

        read_msbuild_xml(input, values)

    # Determine if the output directory needs to be created
    output_dir = __get_path(args.output)

    if not os.path.exists(output_dir):
        os.mkdir(output_dir)
        logging.info('Created output directory %s', output_dir)

    for key, value in values.items():
        output_path = __output_path(toolchain, key, output_dir)

        if os.path.exists(output_path) and not args.overwrite:
            logging.info('Comparing previous output to current')

            __merge_json_values(value, read_msbuild_json(output_path))
        else:
            logging.info('Original output will be overwritten')

        logging.info('Writing MS Build JSON file at %s', output_path)

        __write_json_file(output_path, value)


###########################################################################################
# private joining functions
def __merge_json_values(current, previous):
    """Merges the values between the current and previous run of the script."""
    for value in current:
        name = value['name']

        # Find the previous value
        previous_value = __find_and_remove_value(previous, value)

        if previous_value is not None:
            flags = value['flags']
            previous_flags = previous_value['flags']

            if flags != previous_flags:
                logging.warning(
                    'Flags for %s are different. Using previous value.', name)

                value['flags'] = previous_flags
        else:
            logging.warning('Value %s is a new value', name)

    for value in previous:
        name = value['name']
        logging.warning(
            'Value %s not present in current run. Appending value.', name)

        current.append(value)


def __find_and_remove_value(list, compare):
    """Finds the value in the list that corresponds with the value of compare."""
    # next throws if there are no matches
    try:
        found = next(value for value in list
                     if value['name'] == compare['name'] and value['switch'] ==
                     compare['switch'])
    except:
        return None

    list.remove(found)

    return found


def __normalize_switch(switch, separator):
    new = switch
    if switch.startswith("/") or switch.startswith("-"):
      new = switch[1:]
    if new and separator:
      new = new + separator
    return new

###########################################################################################
# private xml functions
def __convert(root, tag, values, func):
    """Converts the tag type found in the root and converts them using the func
    and appends them to the values.
    """
    elements = root.getElementsByTagName(tag)

    for element in elements:
        converted = func(element)

        # Append to the list
        __append_list(values, converted)


def __convert_enum(node):
    """Converts an EnumProperty node to JSON format."""
    name = __get_attribute(node, 'Name')
    logging.debug('Found EnumProperty named %s', name)

    converted_values = []

    for value in node.getElementsByTagName('EnumValue'):
        converted = __convert_node(value)

        converted['value'] = converted['name']
        converted['name'] = name

        # Modify flags when there is an argument child
        __with_argument(value, converted)

        converted_values.append(converted)

    return converted_values


def __convert_bool(node):
    """Converts an BoolProperty node to JSON format."""
    converted = __convert_node(node, default_value='true')

    # Check for a switch for reversing the value
    reverse_switch = __get_attribute(node, 'ReverseSwitch')

    if reverse_switch:
        __with_argument(node, converted)

        converted_reverse = copy.deepcopy(converted)

        converted_reverse['switch'] = reverse_switch
        converted_reverse['value'] = 'false'

        return [converted_reverse, converted]

    # Modify flags when there is an argument child
    __with_argument(node, converted)

    return __check_for_flag(converted)


def __convert_string_list(node):
    """Converts a StringListProperty node to JSON format."""
    converted = __convert_node(node)

    # Determine flags for the string list
    flags = vsflags(VSFlags.UserValue)

    # Check for a separator to determine if it is semicolon appendable
    # If not present assume the value should be ;
    separator = __get_attribute(node, 'Separator', default_value=';')

    if separator == ';':
        flags = vsflags(flags, VSFlags.SemicolonAppendable)

    converted['flags'] = flags

    return __check_for_flag(converted)


def __convert_string(node):
    """Converts a StringProperty node to JSON format."""
    converted = __convert_node(node, default_flags=vsflags(VSFlags.UserValue))

    return __check_for_flag(converted)


def __convert_node(node, default_value='', default_flags=vsflags()):
    """Converts a XML node to a JSON equivalent."""
    name = __get_attribute(node, 'Name')
    logging.debug('Found %s named %s', node.tagName, name)

    converted = {}
    converted['name'] = name

    switch = __get_attribute(node, 'Switch')
    separator = __get_attribute(node, 'Separator')
    converted['switch'] = __normalize_switch(switch, separator)

    converted['comment'] = __get_attribute(node, 'DisplayName')
    converted['value'] = default_value

    # Check for the Flags attribute in case it was created during preprocessing
    flags = __get_attribute(node, 'Flags')

    if flags:
        flags = flags.split(',')
    else:
        flags = default_flags

    converted['flags'] = flags

    return converted


def __check_for_flag(value):
    """Checks whether the value has a switch value.

    If not then returns None as it should not be added.
    """
    if value['switch']:
        return value
    else:
        logging.warning('Skipping %s which has no command line switch',
                        value['name'])
        return None


def __with_argument(node, value):
    """Modifies the flags in value if the node contains an Argument."""
    arguments = node.getElementsByTagName('Argument')

    if arguments:
        logging.debug('Found argument within %s', value['name'])
        value['flags'] = vsflags(VSFlags.UserValueIgnored, VSFlags.Continue)


def __preprocess_arguments(root):
    """Preprocesses occurrences of Argument within the root.

    Argument XML values reference other values within the document by name. The
    referenced value does not contain a switch. This function will add the
    switch associated with the argument.
    """
    # Set the flags to require a value
    flags = ','.join(vsflags(VSFlags.UserValueRequired))

    # Search through the arguments
    arguments = root.getElementsByTagName('Argument')

    for argument in arguments:
        reference = __get_attribute(argument, 'Property')
        found = None

        # Look for the argument within the root's children
        for child in root.childNodes:
            # Ignore Text nodes
            if isinstance(child, Element):
                name = __get_attribute(child, 'Name')

                if name == reference:
                    found = child
                    break

        if found is not None:
            logging.info('Found property named %s', reference)
            # Get the associated switch
            switch = __get_attribute(argument.parentNode, 'Switch')

            # See if there is already a switch associated with the element.
            if __get_attribute(found, 'Switch'):
                logging.debug('Copying node %s', reference)
                clone = found.cloneNode(True)
                root.insertBefore(clone, found)
                found = clone

            found.setAttribute('Switch', switch)
            found.setAttribute('Flags', flags)
        else:
            logging.warning('Could not find property named %s', reference)


def __get_attribute(node, name, default_value=''):
    """Retrieves the attribute of the given name from the node.

    If not present then the default_value is used.
    """
    if node.hasAttribute(name):
        return node.attributes[name].value.strip()
    else:
        return default_value


###########################################################################################
# private path functions
def __get_path(path):
    """Gets the path to the file."""
    if not os.path.isabs(path):
        path = os.path.join(os.getcwd(), path)

    return os.path.normpath(path)


def __output_path(toolchain, rule, output_dir):
    """Gets the output path for a file given the toolchain, rule and output_dir"""
    filename = '%s_%s.json' % (toolchain, rule)
    return os.path.join(output_dir, filename)


###########################################################################################
# private JSON file functions
def __read_json_file(path):
    """Reads a JSON file at the path."""
    with open(path, 'r') as f:
        return json.load(f)


def __write_json_file(path, values):
    """Writes a JSON file at the path with the values provided."""
    # Sort the keys to ensure ordering
    sort_order = ['name', 'switch', 'comment', 'value', 'flags']
    sorted_values = [
        OrderedDict(
            sorted(
                value.items(), key=lambda value: sort_order.index(value[0])))
        for value in values
    ]

    with open(path, 'w') as f:
        json.dump(sorted_values, f, indent=2, separators=(',', ': '))
        f.write("\n")

###########################################################################################
# private list helpers
def __append_list(append_to, value):
    """Appends the value to the list."""
    if value is not None:
        if isinstance(value, list):
            append_to.extend(value)
        else:
            append_to.append(value)

###########################################################################################
# main entry point
if __name__ == "__main__":
    main()
