# 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={}):
    """Reads the MS Build XML file at the path and returns its contents.

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

    # 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=[]):
    """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 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()
