############################################################################
# Copyright 2016-2017 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
############################################################################

"""use scons -k to invoke all builds regardless of unit test failures
"""
import string
import sys
import SCons.Script
import os.path
import subprocess
from subprocess import Popen, PIPE
from parts import *
import re
import tempfile
import shutil
from collections import OrderedDict

def get_parts_versions(env):
    """Get Parts related versions given SCons environment env"""
    return OrderedDict({'python': string.split(sys.version, " ", 1)[0],
                        'scons': str(SCons.__version__),
                        'parts': str(PartsExtensionVersion())})

def get_toolchain_versions(env):
    """Get version of compilation toolchain given SCons environment env"""
    versions = OrderedDict()
    if 'MSVC_VERSION' in env:
        versions['compiler'] = 'MSVC ' + env['MSVC_VERSION']
        cmd = env.subst('echo int main(){return 0;} > a.cpp'
                        ' | $CXX $CCFLAGS a.cpp /link /verbose')
        defaultlib_regexp = r'.*Searching (.*\.lib).*'
    elif 'GCC_VERSION' in env:
        versions['compiler'] = 'GCC ' + env['GCC_VERSION']
        if 'GXX_VERSION' in env:
            versions['compiler'] += ' and GXX ' + env['GXX_VERSION']
            if os.name == 'nt':
                cmd = env.subst('echo int main(){return 0;}'
                                ' | $CXX $CCFLAGS -xc++ -Wl,--verbose -')
            else:
                cmd = env.subst('echo "int main(){return 0;}"'
                                ' | $CXX $CCFLAGS -xc++ -Wl,--verbose -')
        else:
            if os.name == 'nt':
                cmd = env.subst('echo int main(){return 0;}'
                                ' | $CXX $CCFLAGS -xc++ -Wl,--verbose -')
            else:
                cmd = env.subst('echo "int main(){return 0;}"'
                                ' | $CC  $CCFLAGS -xc   -Wl,--verbose -')
        if os.name == 'nt':
            defaultlib_regexp = r'\n.* open (.*) succeeded'
        else:
            defaultlib_regexp = r'[\n(](/.*\.so[-.\da-fA-F]*).*'

    # Intel C compiler always depends from base toolchain
    if 'INTELC_VERSION' in env:
        versions['compiler'] = 'INTELC {0} with {1}'.format(
            env['INTELC_VERSION'],
            versions['compiler'])

    env['ENV']['PATH'] = str(env['ENV']['PATH'])
    temp_dir = tempfile.mkdtemp()
    try:
        proc = subprocess.Popen(cmd,
                                cwd=temp_dir,
                                env=env['ENV'],
                                shell=True,
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, _ = proc.communicate()
        if proc.returncode != 0:
            versions['default_libs'] = 'failure executing: "{0}"'.format(cmd)
        else:
            default_libs = list(
                set(re.findall(defaultlib_regexp, stdout, re.M)))
            if 'MSVC_VERSION' in env:
                # for windows additionally report versions of Windows Kit used
                runtime_version_set = set()
                for lib_path in default_libs:
                    path_components = os.path.realpath(lib_path).split(os.sep)
                    if 'Windows Kits' in path_components:
                        i = path_components.index('Windows Kits')
                        runtime_version_set.add(
                            'Windows Kits {0} {1}'.format(path_components[i + 1],
                                                          path_components[i + 3]))
                versions['sdk_or_libc'] = '; '.join(list(runtime_version_set))
            else:
                # for posix additionally report versions of libc used
                versions['sdk_or_libc'] = os.path.split(os.path.realpath(
                    next((lib for lib in default_libs if
                          'libc' in lib.lower() and 'libcilk' not in lib.lower()), None)))[1]
            versions['default_libs'] = default_libs
    finally:
        shutil.rmtree(temp_dir)

    return versions


def log_versions(env, include_toolchain=True):
    """Log tools and libraries versions given SCons environment env

    Args:
        env: Scons environment.
        include_toolchain: Log version of compilation toolchain if True.
    """

    versions = get_parts_versions(env)
    if include_toolchain:
        versions.update(get_toolchain_versions(env))

    print "**************** VERSIONS *************"
    long_names = {
        'python': 'Python Version',
        'scons': 'SCons  Version',
        'parts': 'Parts  Version',
        'compiler': 'Compiler Version',
        'sdk_or_libc': 'Libc/SDK',
        'default_libs': 'Default Libs'
    }
    for name, value in versions.iteritems():
        if not isinstance(value, list):
            print '* {0}: {1}'.format(long_names.get(name, name), value)
        else:
            print '* {0}:\n* \t{1}'.format(long_names.get(name, name),
                                           '\n* \t'.join(sorted(value)))
    print "***************************************"


def include_parts(part_list, **kwargs):
    for parts_file in part_list:
        if os.path.isfile(DefaultEnvironment().subst(parts_file)):
            Part(parts_file=parts_file, **kwargs)


######## Part groups ####################################################
ipp_parts = ['ext/ipp/ippcp.parts']
utest_parts = ['ext/gtest/gtest.parts',
               'epid/common-testhelper/common-testhelper.parts']
common_parts = ['epid/common/common.parts']
member_parts = ['epid/member/member.parts']
verifier_parts = ['epid/verifier/verifier.parts']
util_parts = ['example/util/util.parts']
example_parts = ['ext/argtable3/argtable3.parts',
                 'example/verifysig/verifysig.parts',
                 'example/signmsg/signmsg.parts',
                 'example/data/data.parts',
                 'example/compressed_data/compressed_data.parts']
sizing_parts = ['example/util/util_static.parts',
                'example/signmsg/signmsg_shared.parts',
                'example/verifysig/verifysig_shared.parts',
                'example/verifysig/verifysig11_shared.parts']
example_static_parts = ['example/util/util_static.parts',
                        'example/signmsg/signmsg_static.parts',
                        'example/verifysig/verifysig_static.parts']
tools_parts = ['tools/revokegrp/revokegrp.parts',
               'tools/revokekey/revokekey.parts',
               'tools/revokesig/revokesig.parts',
               'tools/extractkeys/extractkeys.parts',
               'tools/extractgrps/extractgrps.parts']
testbot_test_parts = ['test/testbot/testbot.parts',
                      'test/testbot/signmsg/signmsg_testbot.parts',
                      'test/testbot/verifysig/verifysig_testbot.parts',
                      'test/testbot/integration/integration_testbot.parts',
                      'test/testbot/ssh_remote/ssh_remote_testbot.parts',
                      'test/testbot/revokegrp/revokegrp_testbot.parts',
                      'test/testbot/revokekey/revokekey_testbot.parts',
                      'test/testbot/revokesig/revokesig_testbot.parts',
                      'test/testbot/extractkeys/extractkeys_testbot.parts',
                      'test/testbot/extractgrps/extractgrps_testbot.parts',
                      'tools/reports/reports.parts']
tss_test_parts = ['test/tss/tss.parts']
package_parts = ['ext/gtest/gtest.parts',
                 'ext/ipp/ippcp.parts',
                 'package.parts']
memory_profiler_parts = ['tools/memory_profiler/memory_profiler.parts']
internal_tools_parts = ['ext/argtable3/argtable3.parts',
                        'tools/ikgfwrapper/ikgfwrapper.parts']
epid_data = ['test/epid_data/epid_data.parts']
perf_benchmark_parts = ['ext/google_benchmark/google_benchmark.parts',
                        'test/performance/performance.parts']
memory_benchmark_parts = ['test/dynamic_memory/dynamic_memory.parts']
######## End Part groups ###############################################
######## Commandline option setup #######################################
product_variants = [
    'production',
    'internal-test',
    'package-epid-sdk',
    'internal-tools',
    'benchmark',
    'tiny',
    'internal-test-tiny'
]

default_variant = 'production'


def is_production():
    return GetOption("product-variant") == 'production'


def is_internal_test():
    return GetOption("product-variant") == 'internal-test'


def is_internal_tools():
    return GetOption("product-variant") == 'internal-tools'


def is_package():
    return GetOption("product-variant") == 'package-epid-sdk'


def is_benchmark():
    return GetOption("product-variant") == 'benchmark'

def is_tiny():
    return GetOption("product-variant") == 'tiny'

def is_internal_test_tiny():
    return GetOption("product-variant") == 'internal-test-tiny'


def use_commercial_ipp():
    return GetOption("use-commercial-ipp")


def use_tss():
    return GetOption("use-tss")


def config_has_instrumentation():
    return any(DefaultEnvironment().isConfigBasedOn(config_name)
               for config_name in ['instr_release'])


def variant_dirname():
    s = GetOption("product-variant")
    if s == 'production':
        return 'epid-sdk'
    elif s == 'package-epid-sdk':
        return 'epid-sdk'
    elif s == 'tiny':
        return 'epid-sdk'
    else:
        return s


AddOption("--product-variant", "--prod-var", nargs=1,
          help=("Select product variant to build. Possible "
                "options are: {0}. The default is {1} if no option "
                "is specified").format(", ".join(product_variants),
                                       default_variant),
          action='store', dest='product-variant', type='choice',
          choices=product_variants, default=default_variant)

AddOption("--use-commercial-ipp",
          help=("Link with commercial IPP. The IPPCRYPTOROOT environment "
                "variable must be set."),
          action='store_true', dest='use-commercial-ipp',
          default=False)

AddOption("--use-tss",
          help=("Link with TPM TSS. The TSSROOT environment variable "
                "must be set."),
          action='store_true', dest='use-tss',
          default=False)

AddOption("--ipp-shared",
          help=("Build /ext/ipp as shared library."),
          action='store_true', dest='ipp-shared',
          default=False)

AddOption("--enable-sanitizers",
          help=("Build with sanitizers (https://github.com/google/sanitizers)."),
          action='store_true', dest='sanitizers',
          default=False)

AddOption("--sanitizers-recover",
          help=("Configure sanititzers to recover and continue execution "
                "on error found. Only applicable when sanitizers are enabled."
                "See --enable-sanitizers option."),
          action='store_true', dest='sanitizers-recover',
          default=False)


SetOptionDefault("PRODUCT_VARIANT", variant_dirname())

######## End Commandline option setup ###################################


# fix for parts 0.10.8 until we get better logic to extract ${CC}
SetOptionDefault('PARTS_USE_SHORT_TOOL_NAMES', 1)


def enable_sanitizers(recover):
    """
        Configures compiler to enable sanitizers.
        Adds sanitizer options to default scons environment such
        that it affects all parts.
    Args:
        recover: Enable sanitizers recovery from errors found when True.
    """
    env = DefaultEnvironment()
    error_msg = None
    try:
       major = int(env.subst('$GCC_VERSION').partition('.')[0])
    except ValueError:
       major = 0

    if major >= 6 and env['TARGET_OS'] == 'posix':
        if 'INTELC_VERSION' not in env:
            ccflags = ['-fsanitize=address,undefined', '-fno-sanitize=alignment',
                       '-fno-sanitize=shift', '-fno-omit-frame-pointer']
            if recover:
                ccflags = ccflags + ['-fsanitize-recover=all', '-fsanitize-recover=address']
            else:
                ccflags = ccflags + ['-fno-sanitize-recover']
            # Extends default flags with sanitizer options
            SetOptionDefault('CCFLAGS', ccflags)
            SetOptionDefault('LIBS', ['asan', 'ubsan'])
        else:
            error_msg = """
                Build with sanitizers is not supported for Intel(R) C++ Compiler.
                Try scons --toolchain=gcc_6 --target=posix
                """
    else:
        # User experience with sanitizers in GCC 4.8 is not great. Use at least GCC 6.x.
        error_msg = """
            Build with sanitizers is only supported for GCC version greater than
            6.x targeting posix OS. Current GCC version is "{0}" and OS target is "{1}".
            Try scons --toolchain=gcc_6 --target=posix
            """.format(env.get('GCC_VERSION', 'unknown'), env.get('TARGET_OS', 'unknown'))
    if error_msg is not None:
        env.PrintError(error_msg)


def set_default_production_options():
    SetOptionDefault('CONFIG', 'release')

    SetOptionDefault('TARGET_VARIANT', '${TARGET_OS}-${TARGET_ARCH}')

    SetOptionDefault('INSTALL_ROOT',
                     '#_install/${PRODUCT_VARIANT}')

    SetOptionDefault('INSTALL_TOOLS_BIN',
                     '$INSTALL_ROOT/tools')

    SetOptionDefault('INSTALL_SAMPLE_BIN',
                     '$INSTALL_ROOT/example')

    SetOptionDefault('INSTALL_EPID_INCLUDE',
                     '$INSTALL_ROOT/include/epid')

    SetOptionDefault('INSTALL_IPP_INCLUDE',
                     '$INSTALL_ROOT/include/ext/ipp/include')

    SetOptionDefault('INSTALL_TEST_BIN',
                     '$INSTALL_ROOT/test')

    SetOptionDefault('INSTALL_LIB',
                     '$INSTALL_ROOT/lib/${TARGET_VARIANT}')

    SetOptionDefault('INSTALL_SAMPLE_DATA',
                     '$INSTALL_ROOT/example')

    SetOptionDefault('INSTALL_TOOLS_DATA',
                     '$INSTALL_ROOT/tools')

    SetOptionDefault('PACKAGE_DIR',
                     '#_package')

    SetOptionDefault('PACKAGE_ROOT',
                     '#_package/${PRODUCT_VARIANT}')

    SetOptionDefault('ROOT',
                     '#')

    SetOptionDefault('PACKAGE_NAME',
                     '{PRODUCT_VARIANT}')


if GetOption("sanitizers"):
    enable_sanitizers(GetOption("sanitizers-recover"))

if is_production():
    set_default_production_options()
    ipp_mode = ['install_lib']
    if use_commercial_ipp():
        ipp_mode.append('use_commercial_ipp')
    sdk_mode = ['install_lib']
    if use_tss():
        sdk_mode.append('use_tss')
    if GetOption('ipp-shared'):
        ipp_mode.append('build_ipp_shared')
    include_parts(ipp_parts, mode=ipp_mode,
                  INSTALL_INCLUDE='${INSTALL_IPP_INCLUDE}')
    include_parts(utest_parts + common_parts +
                  member_parts + verifier_parts,
                  mode=sdk_mode,
                  INSTALL_INCLUDE='${INSTALL_EPID_INCLUDE}')
    include_parts(util_parts + example_parts,
                  INSTALL_INCLUDE='${INSTALL_EPID_INCLUDE}',
                  INSTALL_BIN='${INSTALL_SAMPLE_BIN}',
                  INSTALL_DATA='${INSTALL_SAMPLE_DATA}')
    include_parts(tools_parts,
                  INSTALL_BIN='${INSTALL_TOOLS_BIN}',
                  INSTALL_DATA='${INSTALL_TOOLS_DATA}')
    Default('all')
    Default('utest::')
    if not use_tss():
        Default('run_utest::')

if is_internal_test():
    set_default_production_options()
    sdk_mode = []
    if use_tss():
        sdk_mode.append('use_tss')
        include_parts(tss_test_parts)
    include_parts(ipp_parts)
    include_parts(utest_parts + common_parts +
                  member_parts + verifier_parts,
                  mode=sdk_mode)
    include_parts(util_parts + example_parts,
                  INSTALL_BIN='${INSTALL_SAMPLE_BIN}',
                  INSTALL_DATA='${INSTALL_SAMPLE_DATA}')
    include_parts(sizing_parts,
                  INSTALL_BIN='${INSTALL_SAMPLE_BIN}')
    include_parts(tools_parts, INSTALL_BIN='${INSTALL_TOOLS_BIN}')
    include_parts(testbot_test_parts)
    Default('all')

if is_internal_tools():
    set_default_production_options()
    include_parts(ipp_parts + utest_parts + common_parts + verifier_parts + member_parts + util_parts)
    include_parts(internal_tools_parts + memory_profiler_parts,
                  INSTALL_BIN='${INSTALL_TOOLS_BIN}')
    Default('ikgfwrapper', 'memory_profiler')
    Default('run_utest::memory_profiler::')

if is_benchmark():
    set_default_production_options()
    MODE = []
    if config_has_instrumentation():
        MODE.append('use_memory_profiler')
    ipp_mode = []
    if use_commercial_ipp():
        ipp_mode.append('use_commercial_ipp')

    # install ipp static and ipp shared builds into separate locations
    if GetOption('ipp-shared'):
        ipp_mode.append('build_ipp_shared')
        SetOptionDefault('INSTALL_TEST_BIN',
                         '$INSTALL_ROOT/test_ipp_shared')
        SetOptionDefault('INSTALL_LIB',
                         '$INSTALL_ROOT/lib_ipp_shared')
    else:
        SetOptionDefault('INSTALL_LIB',
                         '$INSTALL_ROOT/lib')

    # do not allow file links to keep previous builds intact
    SetOptionDefault('CCOPY_LOGIC', 'copy')

    include_parts(ipp_parts, config_independent=True, mode=MODE + ipp_mode,
                  INSTALL_BIN='${INSTALL_TEST_BIN}')
    include_parts(example_static_parts + utest_parts + perf_benchmark_parts +
                  common_parts + verifier_parts +
                  sizing_parts + epid_data,
                  config_independent=True,
                  mode=MODE,
                  INSTALL_BIN='${INSTALL_TEST_BIN}')

    member_mode = ['install_lib']
    member_cfg = ('embedded' if not DefaultEnvironment().isConfigBasedOn(
        'debug') and not config_has_instrumentation() else DefaultEnvironment().subst('$CONFIG'))
    Part(parts_file='epid/common/tinycommon.parts', CONFIG=member_cfg)
    Part(parts_file='epid/member/tinymember.parts', CONFIG=member_cfg,
         config_independent=True, mode=MODE + member_mode, INSTALL_BIN='${INSTALL_TEST_BIN}')

    if config_has_instrumentation():
        include_parts(memory_benchmark_parts + memory_profiler_parts,
                      config_independent=True,
                      mode=MODE,
                      INSTALL_BIN='${INSTALL_TEST_BIN}')

    Default('build::')

if is_package():
    set_default_production_options()
    include_parts(package_parts,
                  mode=['install_package'],
                  INSTALL_TOP_LEVEL='${PACKAGE_ROOT}')
    Default('package')

if is_tiny():
    set_default_production_options()
    ### Member
    Part(parts_file='ext/gtest/gtest.parts')
    member_mode = ['install_lib']
    member_cfg = ('embedded'
                  if not DefaultEnvironment().isConfigBasedOn('debug')
                  else DefaultEnvironment().subst('$CONFIG'))
    Part(parts_file='epid/common/tinycommon.parts', CONFIG=member_cfg)
    Part(parts_file='epid/member/tinymember.parts', CONFIG=member_cfg,
         config_independent=True, mode=member_mode)
    Default('member::')
    Default('run_utest::member::')
    ### Verifier, samples and tools
    verifier_mode = ['install_lib']
    ipp_mode = ['install_lib']
    if use_commercial_ipp():
        ipp_mode.append('use_commercial_ipp')
    if GetOption('ipp-shared'):
        ipp_mode.append('build_ipp_shared')
    include_parts(ipp_parts, mode=ipp_mode,
                  INSTALL_INCLUDE='${INSTALL_IPP_INCLUDE}')
    Part(parts_file='epid/common-testhelper/common-testhelper.parts',
         config_independent=True)
    include_parts(common_parts + verifier_parts,
                  mode=verifier_mode,
                  INSTALL_INCLUDE='${INSTALL_EPID_INCLUDE}')
    include_parts(util_parts + example_parts,
                  INSTALL_INCLUDE='${INSTALL_EPID_INCLUDE}',
                  INSTALL_BIN='${INSTALL_SAMPLE_BIN}',
                  INSTALL_DATA='${INSTALL_SAMPLE_DATA}')
    include_parts(tools_parts,
                  INSTALL_BIN='${INSTALL_TOOLS_BIN}',
                  INSTALL_DATA='${INSTALL_TOOLS_DATA}')
    Default('all')
    Default('utest::')

if is_internal_test_tiny():
    set_default_production_options()
    sdk_mode = []
    ### Member
    Part(parts_file='ext/gtest/gtest.parts')
    member_cfg = ('embedded'
                  if not DefaultEnvironment().isConfigBasedOn('debug')
                  else DefaultEnvironment().subst('$CONFIG'))
    Part(parts_file='epid/common/tinycommon.parts', CONFIG=member_cfg)
    Part(parts_file='epid/member/tinymember.parts', CONFIG=member_cfg,
         config_independent=True, mode=sdk_mode)
    ### Verifier, samples and tools
    include_parts(ipp_parts)
    Part(parts_file='epid/common-testhelper/common-testhelper.parts',
         config_independent=True)
    include_parts(common_parts + verifier_parts,
                  mode=sdk_mode)
    include_parts(util_parts + example_parts,
                  INSTALL_BIN='${INSTALL_SAMPLE_BIN}',
                  INSTALL_DATA='${INSTALL_SAMPLE_DATA}')
    include_parts(tools_parts, INSTALL_BIN='${INSTALL_TOOLS_BIN}')
    include_parts(testbot_test_parts)
    Default('build::')

log_versions(DefaultEnvironment(), not is_package())
