#!/usr/bin/env python
# Post-install script for Linux:  Tries to install the desktop, menu, icons,
# and mime type files

# XXX This is no longer used.  Save for now since it may handle older Linux 
# XXX dists, although possibly ones Wing 5+ won't run on anyway.  Not uninstalling
# XXX icons is no longer needed since we no longer treat 5.1 as separate from 5.0.

import os
import sys
import shutil
import subprocess

SPEC = '~~PRODUCT_SPEC_VERSION~~'

if 'WINGHOME' in os.environ:
  WINGHOME = os.environ['WINGHOME']
else:
  WINGHOME = '/usr/lib/%s' % SPEC

if not '--uninstall' in sys.argv:
  logdir = WINGHOME
  if not os.path.exists(logdir):
    os.makedirs(logdir, 0755)
  logfile = os.path.join(logdir, 'desktop-install.log')
  logf = open(logfile, 'a', encoding='utf-8')
else:
  import tempfile
  logfd, logfile = tempfile.mkstemp('.log', 'wingide-desktop-uninstall')
  logf = os.fdopen(logfd, 'a')
  try:
    os.unlink(os.path.join(WINGHOME, 'desktop-install.log'))
  except:
    pass
  
def p(*args):
  out = ' '.join(args) + '\n'
  logf.write(out)
    
RESOURCES_DIR = os.path.join(WINGHOME, 'resources')
DESKTOP_DIR = os.path.join(RESOURCES_DIR, 'linux', 'desktop')
ICON_GROUPS = ['hicolor', 'gnome']
ICON_SIZES = ['16', '32', '64', '48', '128']

# Desktop and mime type files
kInstallFiles = [
  (os.path.join(DESKTOP_DIR, 'wingide.desktop'), '/usr/share/applications/%s.desktop' % SPEC),
  (os.path.join(DESKTOP_DIR, 'wingide.xml'), '/usr/share/mime/packages/%s.xml' % SPEC),
]  

# Icon files
kNotRemoving = []
for group in ICON_GROUPS:
  for size in ICON_SIZES:
    
    # Application icon
    source = os.path.join(RESOURCES_DIR, 'wing%s.png' % size)
    target = '/usr/share/icons/%s/%sx%s/apps/%s.png' % (group, size, size, SPEC)
    kInstallFiles.append((source, target))
    
    # Project file icon (Do not uninstall these to avoid breaking
    # another #.# release of Wing)
    source = os.path.join(RESOURCES_DIR, 'wing%s.png' % size)
    target = '/usr/share/icons/%s/%sx%s/mimetypes/application-x-wing-ide-project.png' % (group, size, size)
    if not '--uninstall' in sys.argv:
      kInstallFiles.append((source, target))
    else:
      kNotRemoving.append(target)

# Post-copy commands
kCommands = [
  'update-mime-database /usr/share/mime',
  'gtk-update-icon-cache $THEME',
]

def Install():
  """Install files"""

  p('-' * 80)
  p('Starting install')
  
  for source, dest in kInstallFiles:
    _CopyFile(source, dest)
    
  for cmd in kCommands:
    _ExecuteCommand(cmd)
    
  p('Install complete')
  
def UnInstall():
  """Uninstall files"""
  
  p('-' * 80)
  p('Starting uninstall')
  
  if kNotRemoving:
    p("NOTE: The following items are not being removed to avoid breaking another Wing version:")
  for dest in kNotRemoving:
    p("  %s" % dest)
    
  for source, dest in kInstallFiles:
    _RemoveFile(dest)
    
  for cmd in kCommands:
    _ExecuteCommand(cmd)
      
  p('Uninstall complete')
  
def _CopyFile(src, dest):
  
  #_EnsureDirExists(dest)

  # Make destination file writable if needed
  if os.path.exists(dest) and not os.access(dest, os.W_OK):
    try:
      mode = os.stat(dest)[0]
      mode = mode | 0200
      os.chmod(dest, mode)
      p("NOTE: Set mode 0200 on existing dest file %s" % dest)
    except:
      p("ERROR: Failed to replace %s" % dest)
      return
    
  # Don't copy if dest dir doesn't exist
  dirname = os.path.dirname(dest)
  if not os.path.isdir(dirname):
    p("NOTE: Skipping %s -- target directory not found" % dest)
    return

  try:
    shutil.copy2(src, dest)
    p("Copied %s to %s" % (src, dest))
  except:
    p("ERROR: Failed to copy %s to %s" % (src, dest))

def _ExecuteCommand(cmd):
  try:
    p("Executing %s" % cmd)
    f = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                         close_fds=True, shell=True)
    err = f.wait()
    output = f.stdout.read()
    p(output.rstrip())
    if err != 0:
      p("  WARNING: Non-zero return (%i)" % (err, cmd))
  except:
    p("  ERROR: Failed to execute %s" % cmd)

def _RemoveFile(fn):
  if not os.path.exists(fn):
    return
  try:
    os.remove(fn)
    p("Removed: %s" % fn)
  except:
    p("ERROR: Failed to remove: %s" % fn)

if '--uninstall' in sys.argv:
  UnInstall()
else:
  Install()
  
logf.close()

