#!/usr/bin/env python
# Scans the source tree for `.def' and `.la' files, deduces .lib file names from their names & contents and calls lib.exe to generate these .lib files.
# Requires Python 2.6.x
# Usage: gen_msvc_libs.py <bash | cmd> [def | lib | both]
# bash = script is launched from sh under msys, use cp and rm, assume that $(pwd) is toplevel source directory and assume that libdir is *nix-style path
# cmd = script is launched from cmd.exe, use copy and del, assume that %CD% is <package>/lib directory (where .la files are stored), create .lib's from .def's (i.e. 'lib' mode)
# def = copy def files to install directory (default for 'bash' mode, not possible for 'cmd' mode)
# lib = create lib files in the install directory (default for 'cmd' mode)
# both = def and lib
# Example:
#   ./win32/common/gen_msvc_libs.py bash both
#     Should be called right after `make install' to install .def and .lib files
#   .\gen_msvc_libs.py cmd
#     Should be called in Windows shell from install directory to generate .lib files from installed .dif files (obviously, you have to redistribute this script with .dif files)

from __future__ import print_function
import os, re, sys, subprocess

action = "def"
workenv = None
if len(sys.argv) == 3:
  action = sys.argv[2]
  workenv = sys.argv[1]
elif len(sys.argv) == 2:
  workenv = sys.argv[1]
else:
  exit(0)

if workenv != "bash" and workenv != "cmd":
  exit(0)

if workenv == "cmd":
  action = "lib"

def copyshell(root, dest, file, newname=None):
  if newname is None:
    newname = file
  fromfile = None
  tofile = None
  if workenv == "bash":
    fromfile = root + "/" + file
    tofile = dest + "/" + newname
  else:
    fromfile = os.path.join(root, file)
    tofile = os.path.join(dest, newname)

  if workenv == "bash":
    print("cp \"{0}\" \"{1}\"".format(fromfile, tofile))
    retcode = subprocess.call(["cp", fromfile, tofile])
  else:
    print("copy \"{0}\" \"{1}\"".format(fromfile, tofile))
    retcode = subprocess.call(["cmd", "/C", "copy", fromfile, tofile])
  

def delshell(root, filename):
  fullname = None
  if workenv == "bash":
    fullname = root + "/" + filename
  else:
    fullname = os.path.join(root, filename)
  if workenv == "bash":
    print("rm {0}".format(fullname))
    retcode = subprocess.call(["rm", fullname])
  else:
    print("del {0}".format(fullname))
    retcode = subprocess.call(["cmd", "/C", "del", fullname])

def makelib(root, deffile, file, dest):
  libname = file[:-3] + ".lib"
  defname = deffile
  if workenv == "bash":
    defname = deffile[:-7] + "def"

  if action == "def" or action == "both":
    copyshell(root, dest, deffile, defname)
  if action != "lib" and action != "both":
    return
  
  if root != "." or deffile != defname:
    copyshell(root, ".", deffile, defname)

  print("lib.exe /MACHINE:X86 /NOLOGO /DEF:{0} /OUT:{1}".format(defname, libname))
  retcode = subprocess.call(["lib.exe", "/MACHINE:X86", "/NOLOGO", "/DEF:" + defname, "/OUT:" + libname])

  if dest != ".":
    copyshell(".", dest, libname)
    delshell(".", libname)
    if deffile != defname:
      delshell(".", defname)
  
  delshell(".", file[:-3] + ".exp")


def testla(root, file, dllname):
  filetoopen = os.path.join(root, file)
  f = open(filetoopen, "r")
  found = False
  result = None
  if workenv == "bash":
    for line in f:
      if line == "dlname='" + dllname + "'\n":
        found = True
        break
    if found:
      for line in f:
        if line[:8] == "libdir='":
          result = line[8:-2]
          break

  else:
    for line in f:
      if line[-len(dllname) - 2:-2] == dllname:
        found = True
        result = line[9:-1]
        break

  if result == None:
    found = False

  f.close()
  return (found, result)
    

def finddef(dlldir, dllname):
  for root, dirs, files in os.walk(dlldir):
    for file in files:
      if file == dllname + ".def":
        return file
  return None

def findla(dlldir, dllname):
  for root, dirs, files in os.walk(dlldir):
    for file in files:
      if file[-3:] == ".la":
        found, dest = testla(root, file, dllname)
        if found:
          if workenv == "bash":
            deffile = finddef(root, dllname)
            if deffile and os.path.getsize(os.path.join(root,deffile)) > 8:
              makelib(root, deffile, file, dest)
                
          else:
            print(dllname)
            makelib(root, dllname[:-3] + "def", file, root)
          return
            

def walkdir(dir):
  for root, dirs, files in os.walk(dir):
    for file in files:
      if workenv == "bash":
        if file[-4:] == ".dll":
          findla(root, file)
      else:
        if file[-4:] == ".def":
          findla(root, file[:-3] + "dll")  

    for dir in dirs:
      walkdir(root + dir)
  
walkdir(".")