# Copyright (c) 2009 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 common
import os
import re
import socket # for gethostname
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")
