#!/usr/bin/python

#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""
Runs the static rooting analysis
"""

from subprocess import Popen
import subprocess
import os
import argparse
import sys

def env(config):
    e = os.environ
    e['PATH'] = '%s:%s/bin' % (e['PATH'], config['sixgill'])
    e['XDB'] = '%(sixgill)s/bin/xdb.so' % config
    e['SOURCE_ROOT'] = e['TARGET']
    return e

def fill(command, config):
    try:
        return tuple(s % config for s in command)
    except:
        print("Substitution failed:")
        for fragment in command:
            try:
                fragment % config
            except:
                print("  %s" % fragment)
        raise Hell

def generate_hazards(config, outfilename):
    jobs = []
    for i in range(config['jobs']):
        command = fill(('%(js)s',
                        '%(analysis_scriptdir)s/analyzeRoots.js',
                        '%(gcFunctions_list)s',
                        '%(suppressedFunctions_list)s',
                        '%(gcTypes)s',
                        str(i+1), '%(jobs)s',
                        'tmp.%s' % (i+1,)),
                       config)
        outfile = 'rootingHazards.%s' % (i+1,)
        output = open(outfile, 'w')
        print(' '.join(command) + ' > ' + outfile)
        jobs.append((command, Popen(command, stdout=output, env=env(config))))

    final_status = 0
    while jobs:
        pid, status = os.wait()
        jobs = [ job for job in jobs if job[1].pid != pid ]
        final_status = final_status or status

    if final_status:
        raise subprocess.CalledProcessError(final_status, 'analyzeRoots.js')

    with open(outfilename, 'w') as output:
        command = ['cat'] + [ 'rootingHazards.%s' % (i+1,) for i in range(config['jobs']) ]
        print(' '.join(command) + ' > ' + outfilename)
        subprocess.call(command, stdout=output)

JOBS = { 'dbs':
             (('%(CWD)s/run_complete',
               '--foreground',
               '--build-root=%(objdir)s',
               '--work=dir=work',
               '-b', '%(sixgill)s/bin',
               '--buildcommand=%(buildcommand)s',
               '.'),
              None),

         'callgraph':
             (('%(js)s', '%(analysis_scriptdir)s/computeCallgraph.js'),
              'callgraph.txt'),

         'gcFunctions':
             (('%(js)s', '%(analysis_scriptdir)s/computeGCFunctions.js', '%(callgraph)s'),
              'gcFunctions.txt'),

         'gcFunctions_list':
             (('perl', '-lne', 'print $1 if /^GC Function: (.*)/', '%(gcFunctions)s'),
              'gcFunctions.lst'),

         'suppressedFunctions_list':
             (('perl', '-lne', 'print $1 if /^Suppressed Function: (.*)/', '%(gcFunctions)s'),
              'suppressedFunctions.lst'),

         'gcTypes':
             (('%(js)s', '%(analysis_scriptdir)s/computeGCTypes.js',),
              'gcTypes.txt'),

         'allFunctions':
             (('%(sixgill)s/bin/xdbkeys', 'src_body.xdb',),
              'allFunctions.txt'),

         'hazards':
             (generate_hazards, 'rootingHazards.txt')
         }

def run_job(name, config):
    command, outfilename = JOBS[name]
    print("Running " + name + " to generate " + str(outfilename))
    if hasattr(command, '__call__'):
        command(config, outfilename)
    else:
        command = fill(command, config)
        print(' '.join(command))
        temp = '%s.tmp' % name
        with open(temp, 'w') as output:
            subprocess.check_call(command, stdout=output, env=env(config))
        if outfilename is not None:
            os.rename(temp, outfilename)

config = { 'CWD': os.path.dirname(__file__) }

defaults = [ '%s/defaults.py' % config['CWD'] ]

for default in defaults:
    try:
        execfile(default, config)
    except:
        pass

data = config.copy()

parser = argparse.ArgumentParser(description='Statically analyze build tree for rooting hazards.')
parser.add_argument('target', metavar='TARGET', type=str, nargs='?',
                    help='run starting from this target')
parser.add_argument('--jobs', '-j', default=4, metavar='JOBS', type=int,
                    help='number of simultaneous analyzeRoots.js jobs')
parser.add_argument('--list', const=True, nargs='?', type=bool,
                    help='display available targets')
parser.add_argument('--buildcommand', '--build', '-b', type=str, nargs='?',
                    help='command to build the tree being analyzed')
parser.add_argument('--tag', '-t', type=str, nargs='?',
                    help='name of job, also sets build command to "build.<tag>"')

args = parser.parse_args()
data.update(vars(args))

if args.tag and not args.buildcommand:
    args.buildcommand="build.%s" % args.tag

if args.buildcommand:
    data['buildcommand'] = args.buildcommand
elif 'BUILD' in os.environ:
    data['buildcommand'] = os.environ['BUILD']
else:
    data['buildcommand'] = 'make -j4 -s'

targets = [ 'dbs',
            'callgraph',
            'gcTypes',
            'gcFunctions',
            'gcFunctions_list',
            'suppressedFunctions_list',
            'allFunctions',
            'hazards' ]

if args.list:
    for target in targets:
        command, outfilename = JOBS[target]
        if outfilename:
            print("%s -> %s" % (target, outfilename))
        else:
            print(target)
    sys.exit(0)

for target in targets:
    command, outfilename = JOBS[target]
    data[target] = outfilename

if args.target:
    targets = targets[targets.index(args.target):]

for target in targets:
    run_job(target, data)
