# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Visual Studio user preferences file writer."""

import os
import re
import socket # for gethostname

import gyp.common
import gyp.easy_xml as easy_xml


#------------------------------------------------------------------------------

def _FindCommandInPath(command):
  """If there are no slashes in the command given, this function
     searches the PATH env to find the given command, and converts it
     to an absolute path.  We have to do this because MSVS is looking
     for an actual file to launch a debugger on, not just a command
     line.  Note that this happens at GYP time, so anything needing to
     be built needs to have a full path."""
  if '/' in command or '\\' in command:
    # If the command already has path elements (either relative or
    # absolute), then assume it is constructed properly.
    return command
  else:
    # Search through the path list and find an existing file that
    # we can access.
    paths = os.environ.get('PATH','').split(os.pathsep)
    for path in paths:
      item = os.path.join(path, command)
      if os.path.isfile(item) and os.access(item, os.X_OK):
        return item
  return command

def _QuoteWin32CommandLineArgs(args):
  new_args = []
  for arg in args:
    # Replace all double-quotes with double-double-quotes to escape
    # them for cmd shell, and then quote the whole thing if there
    # are any.
    if arg.find('"') != -1:
      arg = '""'.join(arg.split('"'))
      arg = '"%s"' % arg

    # Otherwise, if there are any spaces, quote the whole arg.
    elif re.search(r'[ \t\n]', arg):
      arg = '"%s"' % arg
    new_args.append(arg)
  return new_args

class Writer(object):
  """Visual Studio XML user user file writer."""

  def __init__(self, user_file_path, version, name):
    """Initializes the user file.

    Args:
      user_file_path: Path to the user file.
      version: Version info.
      name: Name of the user file.
    """
    self.user_file_path = user_file_path
    self.version = version
    self.name = name
    self.configurations = {}

  def AddConfig(self, name):
    """Adds a configuration to the project.

    Args:
      name: Configuration name.
    """
    self.configurations[name] = ['Configuration', {'Name': name}]

  def AddDebugSettings(self, config_name, command, environment = {},
                       working_directory=""):
    """Adds a DebugSettings node to the user file for a particular config.

    Args:
      command: command line to run.  First element in the list is the
        executable.  All elements of the command will be quoted if
        necessary.
      working_directory: other files which may trigger the rule. (optional)
    """
    command = _QuoteWin32CommandLineArgs(command)

    abs_command = _FindCommandInPath(command[0])

    if environment and isinstance(environment, dict):
      env_list = ['%s="%s"' % (key, val)
                  for (key,val) in environment.iteritems()]
      environment = ' '.join(env_list)
    else:
      environment = ''

    n_cmd = ['DebugSettings',
             {'Command': abs_command,
              'WorkingDirectory': working_directory,
              'CommandArguments': " ".join(command[1:]),
              'RemoteMachine': socket.gethostname(),
              'Environment': environment,
              'EnvironmentMerge': 'true',
              # Currently these are all "dummy" values that we're just setting
              # in the default manner that MSVS does it.  We could use some of
              # these to add additional capabilities, I suppose, but they might
              # not have parity with other platforms then.
              'Attach': 'false',
              'DebuggerType': '3',  # 'auto' debugger
              'Remote': '1',
              'RemoteCommand': '',
              'HttpUrl': '',
              'PDBPath': '',
              'SQLDebugging': '',
              'DebuggerFlavor': '0',
              'MPIRunCommand': '',
              'MPIRunArguments': '',
              'MPIRunWorkingDirectory': '',
              'ApplicationCommand': '',
              'ApplicationArguments': '',
              'ShimCommand': '',
              'MPIAcceptMode': '',
              'MPIAcceptFilter': ''
             }]

    # Find the config, and add it if it doesn't exist.
    if config_name not in self.configurations:
      self.AddConfig(config_name)

    # Add the DebugSettings onto the appropriate config.
    self.configurations[config_name].append(n_cmd)

  def WriteIfChanged(self):
    """Writes the user file."""
    configs = ['Configurations']
    for config, spec in sorted(self.configurations.iteritems()):
      configs.append(spec)

    content = ['VisualStudioUserFile',
               {'Version': self.version.ProjectVersion(),
                'Name': self.name
               },
               configs]
    easy_xml.WriteXmlIfChanged(content, self.user_file_path,
                               encoding="Windows-1252")
