#!/usr/bin/env python
#
# Copyright (C) 2017 The Android Open Source Project
#
# 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.
#
# pylint: disable=not-callable, relative-import

# Note that adding top-level imports is discouraged unless they're guaranteed to
# be used. Unnecessary imports eat a measurable number of cycles of this
# wrapper.
import os
import sys

BISECT_STAGE = os.environ.get('BISECT_STAGE')
# We do not need bisect functionality with Goma and clang.
# Goma server does not have bisect_driver, so we only import
# bisect_driver when needed. See http://b/34862041
# We should be careful when doing imports because of Goma.
if BISECT_STAGE:
    import bisect_driver

DEFAULT_BISECT_DIR = os.path.expanduser('~/ANDROID_BISECT')
BISECT_DIR = os.environ.get('BISECT_DIR') or DEFAULT_BISECT_DIR
STDERR_REDIRECT_KEY = 'ANDROID_LLVM_STDERR_REDIRECT'
PREBUILT_COMPILER_PATH_KEY = 'ANDROID_LLVM_PREBUILT_COMPILER_PATH'
DISABLED_WARNINGS_KEY = 'ANDROID_LLVM_FALLBACK_DISABLED_WARNINGS'


def ProcessArgFile(arg_file):
    import shlex

    args = []
    # Read in entire file at once and parse as if in shell
    with open(arg_file, 'rb') as f:
        args.extend(shlex.split(f.read()))
    return args


def write_log(path, command, log):
    import errno
    import fcntl
    import time

    with open(path, 'a+') as f:
        while True:
            try:
                fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
                break
            except IOError as e:
                if e.errno == errno.EAGAIN or e.errno == errno.EACCES:
                    time.sleep(0.5)
        f.write('==================COMMAND:====================\n')
        f.write(' '.join(command) + '\n\n')
        f.write(log)
        f.write('==============================================\n\n')


class CompilerWrapper(object):

    def __init__(self, argv):
        self.argv0_current = argv[0]
        self.args = argv[1:]
        self.execargs = []
        self.real_compiler = None
        self.argv0 = None
        self.append_flags = []
        self.prepend_flags = []
        self.custom_flags = {'--gomacc-path': None}

    def set_real_compiler(self):
        """Find the real compiler with the absolute path."""
        compiler_path = os.path.dirname(self.argv0_current)
        if os.path.islink(__file__):
            compiler = os.path.basename(os.readlink(__file__))
        else:
            compiler = os.path.basename(os.path.abspath(__file__))
        self.real_compiler = os.path.join(compiler_path, compiler + '.real')
        self.argv0 = self.real_compiler

    def process_gomacc_command(self):
        """Return the gomacc command if '--gomacc-path' is set."""
        gomacc = self.custom_flags['--gomacc-path']
        if gomacc and os.path.isfile(gomacc):
            self.argv0 = gomacc
            self.execargs += [gomacc]

    def parse_custom_flags(self):
        i = 0
        args = []
        while i < len(self.args):
            if self.args[i] in self.custom_flags:
                if i >= len(self.args) - 1:
                    sys.exit('The value of {} is not set.'.format(self.args[i]))
                self.custom_flags[self.args[i]] = self.args[i + 1]
                i = i + 2
            else:
                args.append(self.args[i])
                i = i + 1
        self.args = args

    def add_flags(self):
        self.args = self.prepend_flags + self.args + self.append_flags

    def prepare_compiler_args(self, enable_fallback=False):
        self.set_real_compiler()
        self.parse_custom_flags()
        # Goma should not be enabled for new prebuilt.
        if not enable_fallback:
            self.process_gomacc_command()
        self.add_flags()
        self.execargs += [self.real_compiler] + self.args

    def exec_clang_with_fallback(self):
        import subprocess

        # We only want to pass extra flags to clang and clang++.
        if os.path.basename(__file__) in ['clang', 'clang++']:
            # We may introduce some new warnings after rebasing and we need to
            # disable them before we fix those warnings.
            disabled_warnings_env = os.environ.get(DISABLED_WARNINGS_KEY, '')
            disabled_warnings = disabled_warnings_env.split(' ')
            self.execargs += ['-fno-color-diagnostics'] + disabled_warnings

        p = subprocess.Popen(self.execargs, stderr=subprocess.PIPE)
        (_, err) = p.communicate()
        sys.stderr.write(err)
        if p.returncode != 0:
            redirect_path = os.environ[STDERR_REDIRECT_KEY]
            write_log(redirect_path, self.execargs, err)
            fallback_arg0 = os.path.join(os.environ[PREBUILT_COMPILER_PATH_KEY],
                                         os.path.basename(__file__))

            # Delete PREBUILT_COMPILER_PATH_KEY so the fallback doesn't keep
            # calling itself in case of an error.
            del os.environ[PREBUILT_COMPILER_PATH_KEY]

            os.execv(fallback_arg0, [fallback_arg0] + self.execargs[1:])

    def invoke_compiler(self):
        enable_fallback = PREBUILT_COMPILER_PATH_KEY in os.environ
        self.prepare_compiler_args(enable_fallback)
        if enable_fallback:
            self.exec_clang_with_fallback()
        else:
            os.execv(self.argv0, self.execargs)

    def bisect(self):
        self.prepare_compiler_args()
        # Handle @file argument syntax with compiler
        idx = 0
        # The length of self.execargs can be changed during the @file argument
        # expansion, so we need to use while loop instead of for loop.
        while idx < len(self.execargs):
            if self.execargs[idx][0] == '@':
                args_in_file = ProcessArgFile(self.execargs[idx][1:])
                self.execargs = self.execargs[0:idx] + args_in_file +\
                        self.execargs[idx + 1:]
                # Skip update of idx, since we want to recursively expand
                # response files.
            else:
                idx = idx + 1
        bisect_driver.bisect_driver(BISECT_STAGE, BISECT_DIR, self.execargs)


def main(argv):
    cw = CompilerWrapper(argv)
    if BISECT_STAGE and BISECT_STAGE in bisect_driver.VALID_MODES\
            and '-o' in argv:
        cw.bisect()
    else:
        cw.invoke_compiler()


if __name__ == '__main__':
    main(sys.argv)
