import re
import os
import subprocess

from .builder import Builder
from lldbsuite.test import configuration
import lldbsuite.test.lldbutil as lldbutil

REMOTE_PLATFORM_NAME_RE = re.compile(r"^remote-(.+)$")
SIMULATOR_PLATFORM_RE = re.compile(r"^(.+)-simulator$")


def get_os_env_from_platform(platform):
    match = REMOTE_PLATFORM_NAME_RE.match(platform)
    if match:
        return match.group(1), ""
    match = SIMULATOR_PLATFORM_RE.match(platform)
    if match:
        return match.group(1), "simulator"
    return None, None


def get_os_from_sdk(sdk):
    return sdk[:sdk.find('.')], ""


def get_os_and_env():
    if configuration.lldb_platform_name:
        return get_os_env_from_platform(configuration.lldb_platform_name)
    if configuration.apple_sdk:
        return get_os_from_sdk(configuration.apple_sdk)
    return None, None


def get_triple():
    # Construct the vendor component.
    vendor = "apple"

    # Construct the os component.
    os, env = get_os_and_env()
    if os is None or env is None:
        return None, None, None, None

    # Get the SDK from the os and env.
    sdk = lldbutil.get_xcode_sdk(os, env)
    if sdk is None:
        return None, None, None, None

    # Get the version from the SDK.
    version = lldbutil.get_xcode_sdk_version(sdk)
    if version is None:
        return None, None, None, None

    return vendor, os, version, env


def get_triple_str(arch, vendor, os, version, env):
    if None in [arch, vendor, os, version, env]:
        return None

    component = [arch, vendor, os + version]
    if env:
        components.append(env)
    return '-'.join(component)


class BuilderDarwin(Builder):
    def getTriple(self, arch):
        vendor, os, version, env = get_triple()
        return get_triple_str(arch, vendor, os, version, env)

    def getExtraMakeArgs(self):
        """
        Helper function to return extra argumentsfor the make system. This
        method is meant to be overridden by platform specific builders.
        """
        args = dict()

        if configuration.dsymutil:
            args['DSYMUTIL'] = configuration.dsymutil

        if 'internal' in configuration.apple_sdk:
            sdk_root = lldbutil.get_xcode_sdk_root(configuration.apple_sdk)
            if sdk_root:
                private_frameworks = os.path.join(sdk_root, 'System',
                                                  'Library',
                                                  'PrivateFrameworks')
                args['FRAMEWORK_INCLUDES'] = '-F{}'.format(private_frameworks)

        operating_system, env = get_os_and_env()
        if operating_system and operating_system != "macosx":
            builder_dir = os.path.dirname(os.path.abspath(__file__))
            test_dir = os.path.dirname(builder_dir)
            if env == "simulator":
              entitlements_file = 'entitlements-simulator.plist'
            else:
              entitlements_file = 'entitlements.plist'
            entitlements = os.path.join(test_dir, 'make', entitlements_file)
            args['CODESIGN'] = 'codesign --entitlements {}'.format(
                entitlements)
        else:
            args['CODESIGN'] = 'codesign'

        # Return extra args as a formatted string.
        return ['{}={}'.format(key, value) for key, value in args.items()]

    def getArchCFlags(self, arch):
        """Returns the ARCH_CFLAGS for the make system."""
        # Get the triple components.
        vendor, os, version, env = get_triple()
        triple = get_triple_str(arch, vendor, os, version, env)
        if not triple:
            return []

        # Construct min version argument
        version_min = ""
        if env == "simulator":
            version_min = "-m{}-simulator-version-min={}".format(os, version)
        else:
            version_min = "-m{}-version-min={}".format(os, version)

        return ["ARCH_CFLAGS=-target {} {}".format(triple, version_min)]

    def _getDebugInfoArgs(self, debug_info):
        if debug_info == "dsym":
            return ["MAKE_DSYM=YES"]
        return super(BuilderDarwin, self)._getDebugInfoArgs(debug_info)
