#!/usr/bin/env python

"""
fixInstallNames.py: This fixes the OpenMM libraries' install names on Mac
"""
__author__ = "Randall J. Radmer"
__version__ = "1.0"

import os, sys
import glob

from subprocess import Popen
from subprocess import PIPE

def do_cmd(cmd):
    log_string = ""
    p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
    #r_code = os.waitpid(p.pid, 0)[1]
    r_code = p.wait()
    log_string = "%s%s returns %d\n" % (log_string, cmd, r_code)
    out = p.stdout.read()
    if out:
        log_string = "%s%s\n" % (log_string, out)
    err = p.stderr.read()
    if err:
        log_string = "%s%s\n" % (log_string, err)
    return (r_code, log_string)

def fix_mac_install_names(lib_root, libs, plugins):
    returnErr = 0
    log_string = ""

    # So OpenMM libs can be found by the python wrapper library (outer loop)
    # and so the OpenMM libs can find each other (inner loop)
    for file_path0 in libs:
        full_file_path0 = os.path.join(lib_root, file_path0)
        filename0 = os.path.split(file_path0)[-1]
        cmd = 'install_name_tool -id "@rpath/%s" %s' % (filename0,
                                                        full_file_path0)
        (err, s) = do_cmd(cmd)
        log_string = "%s%s" % (log_string, s)
        if err!=0: returnErr=err
        for file_path1 in libs:
            if file_path1==file_path0: continue
            filename1 = os.path.split(file_path1)[-1]
            cmd = 'install_name_tool -change %s "@loader_path/%s" %s' \
                 % (filename1, filename1, full_file_path0)
            (err, s) = do_cmd(cmd)
            log_string = "%s%s" % (log_string, s)
            if err!=0: returnErr=err
        cmd = 'otool -L %s' % (full_file_path0)
        (err, s) = do_cmd(cmd)
        log_string = "%s%s" % (log_string, s)

    for file_path0 in plugins:
        full_file_path0 = os.path.join(lib_root, file_path0)
        filename0 = os.path.split(file_path0)[-1]
        for file_path1 in libs:
            filename1 = os.path.split(file_path1)[-1]
            cmd = 'install_name_tool -change %s "@loader_path/../%s" %s' \
                 % (filename1, filename1, full_file_path0)
            (err, s) = do_cmd(cmd)
            log_string = "%s%s" % (log_string, s)
            if err!=0: returnErr=err
        for file_path1 in plugins:
            filename1 = os.path.split(file_path1)[-1]
            cmd = 'install_name_tool -change %s "@loader_path/%s" %s' \
                 % (filename1, filename1, full_file_path0)
            (err, s) = do_cmd(cmd)
            log_string = "%s%s" % (log_string, s)
            if err!=0: returnErr=err

        cmd = 'otool -L %s' % (full_file_path0)
        (err, s) = do_cmd(cmd)
        log_string = "%s%s" % (log_string, s)

    return (returnErr, log_string)

def usageError():
    sys.stdout.write('usage: %s OpenMM_lib_path\n'
                     % os.path.basename(sys.argv[0]))
    sys.exit(1)

if __name__ == '__main__':
    try:
        lib_path=os.path.abspath(sys.argv[1])
    except IndexError:
        usageError()
    os.chdir(lib_path)

    libs = []
    for filename in glob.glob('lib*.dylib'):
        libs.append(filename)

    plugins = []
    try:
        os.chdir('plugins')
        for filename in glob.glob('lib*.dylib'):
            plugins.append(filename)
    except OSError:
        pass

    os.chdir(lib_path)
    (returnErr, log_string) = fix_mac_install_names(lib_path, libs, plugins)
    sys.stdout.write("Return code = %d\n" % returnErr)
    sys.stdout.write("Command Log:\n%s" % log_string)




