
import json
import os
import subprocess

DRY_RUN = False


def br_call(args):
    if DRY_RUN:
        print('DRY RUN: ' + ' '.join(args))
        return 0
    return subprocess.call(args, stdout=open('/dev/null'), stderr=open('/dev/null'))


class SwiftTools(object):
    """A utility class that enables users to easily find sil-tools without needing
to constantly reform paths to the build directory. Also provides safety by
asserting if one of the tools does not exist at the specified path"""

    def __init__(self, swift_build_dir):
        self.swift_build_dir = swift_build_dir

    def _get_tool(self, name):
        path = os.path.join(self.swift_build_dir, 'bin', name)
        if not os.access(path, os.F_OK):
            error_msg = "Error! {} does not exist at: {}".format(name, path)
            raise RuntimeError(error_msg)
        return path

    @property
    def sil_nm(self):
        """Return the path to sil-nm in the specified swift build directory. Throws a
runtime error if the tool does not exist"""
        return self._get_tool('sil-nm')

    @property
    def swiftc(self):
        """Return the path to swiftc in the specified swift build directory. Throws a
runtime error if the tool does not exist"""
        return self._get_tool('swiftc')

    @property
    def sil_opt(self):
        """Return the path to sil-opt in the specified swift build directory. Throws a
runtime error if the tool does not exist"""
        return self._get_tool('sil-opt')

    @property
    def sil_func_extractor(self):
        """Return the path to sil-func-extractor in the specified swift build
directory. Throws a runtime error if the tool does not exist."""
        return self._get_tool('sil-opt')

    @property
    def sil_passpipeline_dumper(self):
        """Return the path to sil-passpipeline-dumper in the specified swift build
directory. Throws a runtime error if the tool does not exist

        """
        return self._get_tool('sil-passpipeline-dumper')


def maybe_abspath(x):
    if x is None:
        return x
    return os.path.abspath(x)

class SILOptInvoker(object):

    def __init__(self, args, tools, early_passes, extra_args):
        self.tools = tools
        self.module_cache = args.module_cache
        self.sdk = args.sdk
        self.target = args.target
        self.resource_dir = maybe_abspath(args.resource_dir)
        self.work_dir = maybe_abspath(args.work_dir)
        self.module_name = args.module_name
        self.extra_args = extra_args

        # Start by creating our workdir if necessary
        subprocess.check_call(["mkdir", "-p", self.work_dir])

        # Then copy our input file into the work dir
        base_input_file = os.path.basename(args.input_file)
        (base, ext) = os.path.splitext(base_input_file)
        self.base_input_file_stem = base
        self.base_input_file_ext = ".sib"

        # First emit an initial *.sib file. This ensures no matter if we have a
        # *.swiftmodule, *.sil, or *.sib file, we are always using *.sib.
        self._invoke(args.input_file, self.get_suffixed_filename('initial'),
                     [])
        self.input_file = self.get_suffixed_filename('initial+early')

        # Finally, run the initial sil-opt invocation running the
        # early-passes. We will not run them again.
        self._invoke(self.get_suffixed_filename('initial'),
                     self.input_file,
                     early_passes)

    def get_suffixed_filename(self, suffix):
        basename = self.base_input_file_stem + '_' + suffix
        basename += self.base_input_file_ext
        return os.path.join(self.work_dir, basename)

    @property
    def base_args(self):
        x = [self.tools.sil_opt, "-emit-sib"]
        if self.sdk is not None:
            x.append("-sdk=%s" % self.sdk)
        if self.target is not None:
            x.append("-target=%s" % self.target)
        if self.resource_dir is not None:
            x.append("-resource-dir=%s" % self.resource_dir)
        if self.module_cache is not None:
            x.append("-module-cache-path=%s" % self.module_cache)
        if self.module_name is not None:
            x.append("-module-name=%s" % self.module_name)
        return x

    def _invoke(self, input_file, output_file, passes):
        base_args = self.base_args
        base_args.extend([
            input_file,
            '-o', output_file])
        base_args.extend(self.extra_args)
        base_args.extend(passes)
        return br_call(base_args)

    def invoke_with_passlist(self, output_filename, passes):
        return self._invoke(self.input_file, output_filename, passes)


def get_silopt_invoker(args):
    tools = SwiftTools(args.swift_build_dir)

    passes = []
    if len(args.pass_list) == 0:
        json_data = json.loads(subprocess.check_output(
            [tools.sil_passpipeline_dumper, '-Performance']))
        passes = sum((p[2:] for p in json_data if p[0] != 'EarlyModulePasses'), [])
        passes = ['-' + x[1] for x in passes]
    else:
        passes = ['-' + x for x in args.pass_list]

    # We assume we have an early module passes that runs until fix point and
    # that is strictly not what is causing the issue.
    #
    # Everything else runs one iteration.
    early_module_passes = [p[2:] for p in json_data
                           if p[0] == 'EarlyModulePasses'][0]
    early_module_passes = ['-' + x[1] for x in early_module_passes]

    return SILOptInvoker(args, tools, early_module_passes)
