# 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.

"""New implementation of Visual Studio project generation for SCons."""

import os
import random

import gyp.common

# hashlib is supplied as of Python 2.5 as the replacement interface for md5
# and other secure hashes.  In 2.6, md5 is deprecated.  Import hashlib if
# available, avoiding a deprecation warning under 2.6.  Import md5 otherwise,
# preserving 2.4 compatibility.
try:
  import hashlib
  _new_md5 = hashlib.md5
except ImportError:
  import md5
  _new_md5 = md5.new


# Initialize random number generator
random.seed()

# GUIDs for project types
ENTRY_TYPE_GUIDS = {
    'project': '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}',
    'folder': '{2150E333-8FDC-42A3-9474-1A3956D46DE8}',
}

#------------------------------------------------------------------------------
# Helper functions


def MakeGuid(name, seed='msvs_new'):
  """Returns a GUID for the specified target name.

  Args:
    name: Target name.
    seed: Seed for MD5 hash.
  Returns:
    A GUID-line string calculated from the name and seed.

  This generates something which looks like a GUID, but depends only on the
  name and seed.  This means the same name/seed will always generate the same
  GUID, so that projects and solutions which refer to each other can explicitly
  determine the GUID to refer to explicitly.  It also means that the GUID will
  not change when the project for a target is rebuilt.
  """
  # Calculate a MD5 signature for the seed and name.
  d = _new_md5(str(seed) + str(name)).hexdigest().upper()
  # Convert most of the signature to GUID form (discard the rest)
  guid = ('{' + d[:8] + '-' + d[8:12] + '-' + d[12:16] + '-' + d[16:20]
          + '-' + d[20:32] + '}')
  return guid

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


class MSVSSolutionEntry(object):
  def __cmp__(self, other):
    # Sort by name then guid (so things are in order on vs2008).
    return cmp((self.name, self.get_guid()), (other.name, other.get_guid()))


class MSVSFolder(MSVSSolutionEntry):
  """Folder in a Visual Studio project or solution."""

  def __init__(self, path, name = None, entries = None,
               guid = None, items = None):
    """Initializes the folder.

    Args:
      path: Full path to the folder.
      name: Name of the folder.
      entries: List of folder entries to nest inside this folder.  May contain
          Folder or Project objects.  May be None, if the folder is empty.
      guid: GUID to use for folder, if not None.
      items: List of solution items to include in the folder project.  May be
          None, if the folder does not directly contain items.
    """
    if name:
      self.name = name
    else:
      # Use last layer.
      self.name = os.path.basename(path)

    self.path = path
    self.guid = guid

    # Copy passed lists (or set to empty lists)
    self.entries = sorted(list(entries or []))
    self.items = list(items or [])

    self.entry_type_guid = ENTRY_TYPE_GUIDS['folder']

  def get_guid(self):
    if self.guid is None:
      # Use consistent guids for folders (so things don't regenerate).
      self.guid = MakeGuid(self.path, seed='msvs_folder')
    return self.guid


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


class MSVSProject(MSVSSolutionEntry):
  """Visual Studio project."""

  def __init__(self, path, name = None, dependencies = None, guid = None,
               spec = None, build_file = None, config_platform_overrides = None,
               fixpath_prefix = None):
    """Initializes the project.

    Args:
      path: Absolute path to the project file.
      name: Name of project.  If None, the name will be the same as the base
          name of the project file.
      dependencies: List of other Project objects this project is dependent
          upon, if not None.
      guid: GUID to use for project, if not None.
      spec: Dictionary specifying how to build this project.
      build_file: Filename of the .gyp file that the vcproj file comes from.
      config_platform_overrides: optional dict of configuration platforms to
          used in place of the default for this target.
      fixpath_prefix: the path used to adjust the behavior of _fixpath
    """
    self.path = path
    self.guid = guid
    self.spec = spec
    self.build_file = build_file
    # Use project filename if name not specified
    self.name = name or os.path.splitext(os.path.basename(path))[0]

    # Copy passed lists (or set to empty lists)
    self.dependencies = list(dependencies or [])

    self.entry_type_guid = ENTRY_TYPE_GUIDS['project']

    if config_platform_overrides:
      self.config_platform_overrides = config_platform_overrides
    else:
      self.config_platform_overrides = {}
    self.fixpath_prefix = fixpath_prefix
    self.msbuild_toolset = None

  def set_dependencies(self, dependencies):
    self.dependencies = list(dependencies or [])

  def get_guid(self):
    if self.guid is None:
      # Set GUID from path
      # TODO(rspangler): This is fragile.
      # 1. We can't just use the project filename sans path, since there could
      #    be multiple projects with the same base name (for example,
      #    foo/unittest.vcproj and bar/unittest.vcproj).
      # 2. The path needs to be relative to $SOURCE_ROOT, so that the project
      #    GUID is the same whether it's included from base/base.sln or
      #    foo/bar/baz/baz.sln.
      # 3. The GUID needs to be the same each time this builder is invoked, so
      #    that we don't need to rebuild the solution when the project changes.
      # 4. We should be able to handle pre-built project files by reading the
      #    GUID from the files.
      self.guid = MakeGuid(self.name)
    return self.guid

  def set_msbuild_toolset(self, msbuild_toolset):
    self.msbuild_toolset = msbuild_toolset

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


class MSVSSolution:
  """Visual Studio solution."""

  def __init__(self, path, version, entries=None, variants=None,
               websiteProperties=True):
    """Initializes the solution.

    Args:
      path: Path to solution file.
      version: Format version to emit.
      entries: List of entries in solution.  May contain Folder or Project
          objects.  May be None, if the folder is empty.
      variants: List of build variant strings.  If none, a default list will
          be used.
      websiteProperties: Flag to decide if the website properties section
          is generated.
    """
    self.path = path
    self.websiteProperties = websiteProperties
    self.version = version

    # Copy passed lists (or set to empty lists)
    self.entries = list(entries or [])

    if variants:
      # Copy passed list
      self.variants = variants[:]
    else:
      # Use default
      self.variants = ['Debug|Win32', 'Release|Win32']
    # TODO(rspangler): Need to be able to handle a mapping of solution config
    # to project config.  Should we be able to handle variants being a dict,
    # or add a separate variant_map variable?  If it's a dict, we can't
    # guarantee the order of variants since dict keys aren't ordered.


    # TODO(rspangler): Automatically write to disk for now; should delay until
    # node-evaluation time.
    self.Write()


  def Write(self, writer=gyp.common.WriteOnDiff):
    """Writes the solution file to disk.

    Raises:
      IndexError: An entry appears multiple times.
    """
    # Walk the entry tree and collect all the folders and projects.
    all_entries = set()
    entries_to_check = self.entries[:]
    while entries_to_check:
      e = entries_to_check.pop(0)

      # If this entry has been visited, nothing to do.
      if e in all_entries:
        continue

      all_entries.add(e)

      # If this is a folder, check its entries too.
      if isinstance(e, MSVSFolder):
        entries_to_check += e.entries

    all_entries = sorted(all_entries)

    # Open file and print header
    f = writer(self.path)
    f.write('Microsoft Visual Studio Solution File, '
            'Format Version %s\r\n' % self.version.SolutionVersion())
    f.write('# %s\r\n' % self.version.Description())

    # Project entries
    sln_root = os.path.split(self.path)[0]
    for e in all_entries:
      relative_path = gyp.common.RelativePath(e.path, sln_root)
      # msbuild does not accept an empty folder_name.
      # use '.' in case relative_path is empty.
      folder_name = relative_path.replace('/', '\\') or '.'
      f.write('Project("%s") = "%s", "%s", "%s"\r\n' % (
          e.entry_type_guid,          # Entry type GUID
          e.name,                     # Folder name
          folder_name,                # Folder name (again)
          e.get_guid(),               # Entry GUID
      ))

      # TODO(rspangler): Need a way to configure this stuff
      if self.websiteProperties:
        f.write('\tProjectSection(WebsiteProperties) = preProject\r\n'
                '\t\tDebug.AspNetCompiler.Debug = "True"\r\n'
                '\t\tRelease.AspNetCompiler.Debug = "False"\r\n'
                '\tEndProjectSection\r\n')

      if isinstance(e, MSVSFolder):
        if e.items:
          f.write('\tProjectSection(SolutionItems) = preProject\r\n')
          for i in e.items:
            f.write('\t\t%s = %s\r\n' % (i, i))
          f.write('\tEndProjectSection\r\n')

      if isinstance(e, MSVSProject):
        if e.dependencies:
          f.write('\tProjectSection(ProjectDependencies) = postProject\r\n')
          for d in e.dependencies:
            f.write('\t\t%s = %s\r\n' % (d.get_guid(), d.get_guid()))
          f.write('\tEndProjectSection\r\n')

      f.write('EndProject\r\n')

    # Global section
    f.write('Global\r\n')

    # Configurations (variants)
    f.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n')
    for v in self.variants:
      f.write('\t\t%s = %s\r\n' % (v, v))
    f.write('\tEndGlobalSection\r\n')

    # Sort config guids for easier diffing of solution changes.
    config_guids = []
    config_guids_overrides = {}
    for e in all_entries:
      if isinstance(e, MSVSProject):
        config_guids.append(e.get_guid())
        config_guids_overrides[e.get_guid()] = e.config_platform_overrides
    config_guids.sort()

    f.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n')
    for g in config_guids:
      for v in self.variants:
        nv = config_guids_overrides[g].get(v, v)
        # Pick which project configuration to build for this solution
        # configuration.
        f.write('\t\t%s.%s.ActiveCfg = %s\r\n' % (
            g,              # Project GUID
            v,              # Solution build configuration
            nv,             # Project build config for that solution config
        ))

        # Enable project in this solution configuration.
        f.write('\t\t%s.%s.Build.0 = %s\r\n' % (
            g,              # Project GUID
            v,              # Solution build configuration
            nv,             # Project build config for that solution config
        ))
    f.write('\tEndGlobalSection\r\n')

    # TODO(rspangler): Should be able to configure this stuff too (though I've
    # never seen this be any different)
    f.write('\tGlobalSection(SolutionProperties) = preSolution\r\n')
    f.write('\t\tHideSolutionNode = FALSE\r\n')
    f.write('\tEndGlobalSection\r\n')

    # Folder mappings
    # TODO(rspangler): Should omit this section if there are no folders
    f.write('\tGlobalSection(NestedProjects) = preSolution\r\n')
    for e in all_entries:
      if not isinstance(e, MSVSFolder):
        continue        # Does not apply to projects, only folders
      for subentry in e.entries:
        f.write('\t\t%s = %s\r\n' % (subentry.get_guid(), e.get_guid()))
    f.write('\tEndGlobalSection\r\n')

    f.write('EndGlobal\r\n')

    f.close()
