#!/usr/bin/env python
#
# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# A script to generate a windows installer for the editor bundle.
# As input the script takes a zip file, a version and the location
# to store the resulting msi file in.
#
# Usage: ./tools/create_windows_installer.py --version <version>
#            --zip_file_location <zip_file> --msi_location <output>
#            [--wix_bin <wix_bin_location>]
#            [--print_wxs]
#
# This script assumes that wix is either in path or passed in as --wix_bin.
# You can get wix from http://wixtoolset.org/.

import optparse
import os
import shutil
import subprocess
import sys
import utils
import zipfile

# This should _never_ change, please don't change this value.
UPGRADE_CODE = '7bacdc33-2e76-4f36-a206-ea58220c0b44'

# The content of the xml
xml_content = []

# The components we want to add to our feature.
feature_components = []

# Indentation level, each level is indented 2 spaces
current_indentation = 0

def GetOptions():
  options = optparse.OptionParser(usage='usage: %prog [options]')
  options.add_option("--zip_file_location",
      help='Where the zip file including the editor is located.')
  options.add_option("--input_directory",
      help='Directory where all the files needed is located.')
  options.add_option("--msi_location",
      help='Where to store the resulting msi.')
  options.add_option("--version",
      help='The version specified as Major.Minor.Build.Patch.')
  options.add_option("--wix_bin",
      help='The location of the wix binary files.')
  options.add_option("--print_wxs", action="store_true", dest="print_wxs",
                    default=False,
                    help="Prints the generated wxs to stdout.")
  (options, args) = options.parse_args()
  if len(args) > 0:
    raise Exception("This script takes no arguments, only options")
  ValidateOptions(options)
  return options

def ValidateOptions(options):
  if not options.version:
    raise Exception('You must supply a version')
  if options.zip_file_location and options.input_directory:
    raise Exception('Please pass either zip_file_location or input_directory')
  if not options.zip_file_location and not options.input_directory:
    raise Exception('Please pass either zip_file_location or input_directory')
  if (options.zip_file_location and
      not os.path.isfile(options.zip_file_location)):
    raise Exception('Passed in zip file not found')
  if (options.input_directory and
      not os.path.isdir(options.input_directory)):
    raise Exception('Passed in directory not found')

def GetInputDirectory(options, temp_dir):
  if options.zip_file_location:
    ExtractZipFile(options.zip_file_location, temp_dir)
    return os.path.join(temp_dir, 'dart')
  return options.input_directory

# We combine the build and patch into a single entry since
# the windows installer does _not_ consider a change in Patch
# to require a new install.
# In addition to that, the limits on the size are:
# Major: 256
# Minor: 256
# Build: 65536
# To circumvent this we create the version like this:
#   Major.Minor.X
# where X is Build<<9 + Patch
# Example version 1.2.4.14 will go to 1.2.2062
def GetMicrosoftProductVersion(version):
  version_parts = version.split('.')
  if len(version_parts) is not 4:
    raise Exception(
      "Version string (%s) does not follow specification" % version)
  (major, minor, build, patch) = map(int, version_parts)

  if build > 127 or patch > 511:
    raise Exception('Build/Patch can not be above 127/511')
  if major > 255 or minor > 255:
    raise Exception('Major/Minor can not be above 256')

  combined = (build << 9) + patch
  return '%s.%s.%s' % (major, minor, combined)

# Append using the current indentation level
def Append(data, new_line=True):
  str = (('  ' * current_indentation) +
         data +
         ('\n' if new_line else ''))
  xml_content.append(str)

# Append without any indentation at the current position
def AppendRaw(data, new_line=True):
  xml_content.append(data + ('\n' if new_line else ''))

def AppendComment(comment):
  Append('<!--%s-->' % comment)

def AppendBlankLine():
  Append('')

def GetContent():
  return ''.join(xml_content)

def XmlHeader():
  Append('<?xml version="1.0" encoding="UTF-8"?>')

def TagIndent(str, indentation_string):
  return ' ' * len(indentation_string) + str

def IncreaseIndentation():
  global current_indentation
  current_indentation += 1

def DecreaseIndentation():
  global current_indentation
  current_indentation -= 1

class WixAndProduct(object):
  def __init__(self, version):
    self.version = version
    self.product_name = 'Dart Editor'
    self.manufacturer = 'Google Inc.'
    self.upgrade_code = UPGRADE_CODE

  def __enter__(self):
    self.start_wix()
    self.start_product()

  def __exit__(self, *_):
    self.close_product()
    self.close_wix()

  def get_product_id(self):
    # This needs to change on every install to guarantee that
    # we get a full uninstall + reinstall
    # We let wix choose. If we need to do patch releases later on
    # we need to retain the value over several installs.
    return '*'

  def start_product(self):
    product = '<Product '
    Append(product, new_line=False)
    AppendRaw('Id="%s"' % self.get_product_id())
    Append(TagIndent('Version="%s"' % self.version, product))
    Append(TagIndent('Name="%s"' % self.product_name, product))
    Append(TagIndent('UpgradeCode="%s"' % self.upgrade_code,
                     product))
    Append(TagIndent('Language="1033"', product))
    Append(TagIndent('Manufacturer="%s"' % self.manufacturer,
                     product),
           new_line=False)
    AppendRaw('>')
    IncreaseIndentation()

  def close_product(self):
    DecreaseIndentation()
    Append('</Product>')

  def start_wix(self):
    Append('<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">')
    IncreaseIndentation()

  def close_wix(self):
    DecreaseIndentation()
    Append('</Wix>')

class Directory(object):
  def __init__(self, id, name=None):
    self.id = id
    self.name = name

  def __enter__(self):
    directory = '<Directory '
    Append(directory, new_line=False)
    AppendRaw('Id="%s"' % self.id, new_line=self.name is not None)
    if self.name:
      Append(TagIndent('Name="%s"' % self.name, directory), new_line=False)
    AppendRaw('>')
    IncreaseIndentation()

  def __exit__(self, *_):
    DecreaseIndentation()
    Append('</Directory>')

class Component(object):
  def __init__(self, id):
    self.id = 'CMP_%s' % id

  def __enter__(self):
    component = '<Component '
    Append(component, new_line=False)
    AppendRaw('Id="%s"' % self.id)
    Append(TagIndent('Guid="*">', component))
    IncreaseIndentation()

  def __exit__(self, *_):
    DecreaseIndentation()
    Append('</Component>')
    feature_components.append(self.id)

class Feature(object):
  def __enter__(self):
    feature = '<Feature '
    Append(feature, new_line=False)
    AppendRaw('Id="MainFeature"')
    Append(TagIndent('Title="Dart Editor"', feature))
    # Install by default
    Append(TagIndent('Level="1">', feature))
    IncreaseIndentation()

  def __exit__(self, *_):
    DecreaseIndentation()
    Append('</Feature>')

def Package():
  package = '<Package '
  Append(package, new_line=False)
  AppendRaw('InstallerVersion="301"')
  Append(TagIndent('Compressed="yes" />', package))

def MediaTemplate():
  Append('<MediaTemplate EmbedCab="yes" />')

def File(name, id):
  file = '<File '
  Append(file, new_line=False)
  AppendRaw('Id="FILE_%s"' % id)
  Append(TagIndent('Source="%s"' % name, file))
  Append(TagIndent('KeyPath="yes" />', file))

def Shortcut(id, name, ref):
  shortcut = '<Shortcut '
  Append(shortcut, new_line=False)
  AppendRaw('Id="%s"' % id)
  Append(TagIndent('Name="%s"' % name, shortcut))
  Append(TagIndent('Target="%s" />' % ref, shortcut))

def RemoveFolder(id):
  remove = '<RemoveFolder '
  Append(remove, new_line=False)
  AppendRaw('Id="%s"' % id)
  Append(TagIndent('On="uninstall" />', remove))

def RegistryEntry(location):
  registry = '<RegistryValue '
  Append(registry, new_line=False)
  AppendRaw('Root="HKCU"')
  Append(TagIndent('Key="Software\\Microsoft\\%s"' % location, registry))
  Append(TagIndent('Name="installed"', registry))
  Append(TagIndent('Type="integer"', registry))
  Append(TagIndent('Value="1"', registry))
  Append(TagIndent('KeyPath="yes" />', registry))


def MajorUpgrade():
  upgrade = '<MajorUpgrade '
  Append(upgrade, new_line=False)
  down_message = 'You already have a never version installed.'
  AppendRaw('DowngradeErrorMessage="%s" />' % down_message)


# This is a very simplistic id generation.
# Unfortunately there is no easy way to generate good names,
# since there is a 72 character limit, and we have way longer
# paths. We don't really have an issue with files and ids across
# releases since we do full installs.
counter = 0
def FileToId(name):
  global counter
  counter += 1
  return '%s' % counter

def ListFiles(path):
  for entry in os.listdir(path):
    full_path = os.path.join(path, entry)
    id = FileToId(full_path)
    if os.path.isdir(full_path):
      with Directory('DIR_%s' % id, entry):
        ListFiles(full_path)
    elif os.path.isfile(full_path):
      # We assume 1 file per component, a File is always a KeyPath.
      # A KeyPath on a file makes sure that we can always repair and
      # remove that file in a consistent manner. A component
      # can only have one child with a KeyPath.
      with Component(id):
        File(full_path, id)

def ComponentRefs():
  for component in feature_components:
    Append('<ComponentRef Id="%s" />' % component)

def ExtractZipFile(zip, temp_dir):
  print 'Extracting files'
  f = zipfile.ZipFile(zip)
  f.extractall(temp_dir)
  f.close()

def GenerateInstaller(wxs_content, options, temp_dir):
  wxs_file = os.path.join(temp_dir, 'installer.wxs')
  wixobj_file = os.path.join(temp_dir, 'installer.wixobj')
  print 'Saving wxs output to: %s' % wxs_file
  with open(wxs_file, 'w') as f:
    f.write(wxs_content)

  candle_bin = 'candle.exe'
  light_bin = 'light.exe'
  if options.wix_bin:
    candle_bin = os.path.join(options.wix_bin, 'candle.exe')
    light_bin = os.path.join(options.wix_bin, 'light.exe')
  print 'Calling candle on %s' % wxs_file
  subprocess.check_call('%s %s -o %s' % (candle_bin, wxs_file,
                                         wixobj_file))
  print 'Calling light on %s' % wixobj_file
  subprocess.check_call('%s %s -o %s' % (light_bin, wixobj_file,
                                         options.msi_location))
  print 'Created msi file to %s' % options.msi_location


def Main(argv):
  if sys.platform != 'win32':
    raise Exception("This script can only be run on windows")
  options = GetOptions()
  version = GetMicrosoftProductVersion(options.version)
  with utils.TempDir('installer') as temp_dir:
    input_location = GetInputDirectory(options, temp_dir)
    print "Generating wix XML"
    XmlHeader()
    with WixAndProduct(version):
      AppendBlankLine()
      Package()
      MediaTemplate()
      AppendComment('We always do a major upgrade, at least for now')
      MajorUpgrade()

      AppendComment('Directory structure')
      with Directory('TARGETDIR', 'SourceDir'):
        with Directory('ProgramFilesFolder'):
          with Directory('RootInstallDir', 'Dart Editor'):
            AppendComment("Add all files and directories")
            print 'Installing files and directories in xml'
            ListFiles(input_location)
        AppendBlankLine()
        AppendComment("Create shortcuts")
        with Directory('ProgramMenuFolder'):
          with Directory('ShortcutFolder', 'Dart Editor'):
            with Component('shortcut'):
              # When generating a shortcut we need an entry with
              # a KeyPath (RegistryEntry) below - to be able to remove
              # the shortcut again. The RemoveFolder tag is needed
              # to clean up everything
              Shortcut('editor_shortcut', 'Dart Editor',
                       '[RootInstallDir]DartEditor.exe')
              RemoveFolder('RemoveShortcuts')
              RegistryEntry('DartEditor')
      with Feature():
        # We have only one feature and that consist of all the
        # files=components we have listed above"
        ComponentRefs()
    xml = GetContent()
    if options.print_wxs:
      print xml
    GenerateInstaller(xml, options, temp_dir)

if __name__ == '__main__':
  sys.exit(Main(sys.argv))
