# -*- coding: utf-8 -*-
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
""" This module implements the 'scan-build' command API.

To run the static analyzer against a build is done in multiple steps:

 -- Intercept: capture the compilation command during the build,
 -- Analyze:   run the analyzer against the captured commands,
 -- Report:    create a cover report from the analyzer outputs.  """

import sys
import re
import os
import os.path
import json
import argparse
import logging
import subprocess
import multiprocessing
from libscanbuild import initialize_logging, tempdir, command_entry_point
from libscanbuild.runner import run
from libscanbuild.intercept import capture
from libscanbuild.report import report_directory, document
from libscanbuild.clang import get_checkers
from libscanbuild.compilation import split_command

__all__ = ['analyze_build_main', 'analyze_build_wrapper']

COMPILER_WRAPPER_CC = 'analyze-cc'
COMPILER_WRAPPER_CXX = 'analyze-c++'


@command_entry_point
def analyze_build_main(bin_dir, from_build_command):
    """ Entry point for 'analyze-build' and 'scan-build'. """

    parser = create_parser(from_build_command)
    args = parser.parse_args()
    validate(parser, args, from_build_command)

    # setup logging
    initialize_logging(args.verbose)
    logging.debug('Parsed arguments: %s', args)

    with report_directory(args.output, args.keep_empty) as target_dir:
        if not from_build_command:
            # run analyzer only and generate cover report
            run_analyzer(args, target_dir)
            number_of_bugs = document(args, target_dir, True)
            return number_of_bugs if args.status_bugs else 0
        elif args.intercept_first:
            # run build command and capture compiler executions
            exit_code = capture(args, bin_dir)
            # next step to run the analyzer against the captured commands
            if need_analyzer(args.build):
                run_analyzer(args, target_dir)
                # cover report generation and bug counting
                number_of_bugs = document(args, target_dir, True)
                # remove the compilation database when it was not requested
                if os.path.exists(args.cdb):
                    os.unlink(args.cdb)
                # set exit status as it was requested
                return number_of_bugs if args.status_bugs else exit_code
            else:
                return exit_code
        else:
            # run the build command with compiler wrappers which
            # execute the analyzer too. (interposition)
            environment = setup_environment(args, target_dir, bin_dir)
            logging.debug('run build in environment: %s', environment)
            exit_code = subprocess.call(args.build, env=environment)
            logging.debug('build finished with exit code: %d', exit_code)
            # cover report generation and bug counting
            number_of_bugs = document(args, target_dir, False)
            # set exit status as it was requested
            return number_of_bugs if args.status_bugs else exit_code


def need_analyzer(args):
    """ Check the intent of the build command.

    When static analyzer run against project configure step, it should be
    silent and no need to run the analyzer or generate report.

    To run `scan-build` against the configure step might be neccessary,
    when compiler wrappers are used. That's the moment when build setup
    check the compiler and capture the location for the build process. """

    return len(args) and not re.search('configure|autogen', args[0])


def run_analyzer(args, output_dir):
    """ Runs the analyzer against the given compilation database. """

    def exclude(filename):
        """ Return true when any excluded directory prefix the filename. """
        return any(re.match(r'^' + directory, filename)
                   for directory in args.excludes)

    consts = {
        'clang': args.clang,
        'output_dir': output_dir,
        'output_format': args.output_format,
        'output_failures': args.output_failures,
        'direct_args': analyzer_params(args),
        'force_debug': args.force_debug
    }

    logging.debug('run analyzer against compilation database')
    with open(args.cdb, 'r') as handle:
        generator = (dict(cmd, **consts)
                     for cmd in json.load(handle) if not exclude(cmd['file']))
        # when verbose output requested execute sequentially
        pool = multiprocessing.Pool(1 if args.verbose > 2 else None)
        for current in pool.imap_unordered(run, generator):
            if current is not None:
                # display error message from the static analyzer
                for line in current['error_output']:
                    logging.info(line.rstrip())
        pool.close()
        pool.join()


def setup_environment(args, destination, bin_dir):
    """ Set up environment for build command to interpose compiler wrapper. """

    environment = dict(os.environ)
    environment.update({
        'CC': os.path.join(bin_dir, COMPILER_WRAPPER_CC),
        'CXX': os.path.join(bin_dir, COMPILER_WRAPPER_CXX),
        'ANALYZE_BUILD_CC': args.cc,
        'ANALYZE_BUILD_CXX': args.cxx,
        'ANALYZE_BUILD_CLANG': args.clang if need_analyzer(args.build) else '',
        'ANALYZE_BUILD_VERBOSE': 'DEBUG' if args.verbose > 2 else 'WARNING',
        'ANALYZE_BUILD_REPORT_DIR': destination,
        'ANALYZE_BUILD_REPORT_FORMAT': args.output_format,
        'ANALYZE_BUILD_REPORT_FAILURES': 'yes' if args.output_failures else '',
        'ANALYZE_BUILD_PARAMETERS': ' '.join(analyzer_params(args)),
        'ANALYZE_BUILD_FORCE_DEBUG': 'yes' if args.force_debug else ''
    })
    return environment


def analyze_build_wrapper(cplusplus):
    """ Entry point for `analyze-cc` and `analyze-c++` compiler wrappers. """

    # initialize wrapper logging
    logging.basicConfig(format='analyze: %(levelname)s: %(message)s',
                        level=os.getenv('ANALYZE_BUILD_VERBOSE', 'INFO'))
    # execute with real compiler
    compiler = os.getenv('ANALYZE_BUILD_CXX', 'c++') if cplusplus \
        else os.getenv('ANALYZE_BUILD_CC', 'cc')
    compilation = [compiler] + sys.argv[1:]
    logging.info('execute compiler: %s', compilation)
    result = subprocess.call(compilation)
    # exit when it fails, ...
    if result or not os.getenv('ANALYZE_BUILD_CLANG'):
        return result
    # ... and run the analyzer if all went well.
    try:
        # check is it a compilation
        compilation = split_command(sys.argv)
        if compilation is None:
            return result
        # collect the needed parameters from environment, crash when missing
        parameters = {
            'clang': os.getenv('ANALYZE_BUILD_CLANG'),
            'output_dir': os.getenv('ANALYZE_BUILD_REPORT_DIR'),
            'output_format': os.getenv('ANALYZE_BUILD_REPORT_FORMAT'),
            'output_failures': os.getenv('ANALYZE_BUILD_REPORT_FAILURES'),
            'direct_args': os.getenv('ANALYZE_BUILD_PARAMETERS',
                                     '').split(' '),
            'force_debug': os.getenv('ANALYZE_BUILD_FORCE_DEBUG'),
            'directory': os.getcwd(),
            'command': [sys.argv[0], '-c'] + compilation.flags
        }
        # call static analyzer against the compilation
        for source in compilation.files:
            parameters.update({'file': source})
            logging.debug('analyzer parameters %s', parameters)
            current = run(parameters)
            # display error message from the static analyzer
            if current is not None:
                for line in current['error_output']:
                    logging.info(line.rstrip())
    except Exception:
        logging.exception("run analyzer inside compiler wrapper failed.")
    return result


def analyzer_params(args):
    """ A group of command line arguments can mapped to command
    line arguments of the analyzer. This method generates those. """

    def prefix_with(constant, pieces):
        """ From a sequence create another sequence where every second element
        is from the original sequence and the odd elements are the prefix.

        eg.: prefix_with(0, [1,2,3]) creates [0, 1, 0, 2, 0, 3] """

        return [elem for piece in pieces for elem in [constant, piece]]

    result = []

    if args.store_model:
        result.append('-analyzer-store={0}'.format(args.store_model))
    if args.constraints_model:
        result.append('-analyzer-constraints={0}'.format(
            args.constraints_model))
    if args.internal_stats:
        result.append('-analyzer-stats')
    if args.analyze_headers:
        result.append('-analyzer-opt-analyze-headers')
    if args.stats:
        result.append('-analyzer-checker=debug.Stats')
    if args.maxloop:
        result.extend(['-analyzer-max-loop', str(args.maxloop)])
    if args.output_format:
        result.append('-analyzer-output={0}'.format(args.output_format))
    if args.analyzer_config:
        result.append(args.analyzer_config)
    if args.verbose >= 4:
        result.append('-analyzer-display-progress')
    if args.plugins:
        result.extend(prefix_with('-load', args.plugins))
    if args.enable_checker:
        checkers = ','.join(args.enable_checker)
        result.extend(['-analyzer-checker', checkers])
    if args.disable_checker:
        checkers = ','.join(args.disable_checker)
        result.extend(['-analyzer-disable-checker', checkers])
    if os.getenv('UBIVIZ'):
        result.append('-analyzer-viz-egraph-ubigraph')

    return prefix_with('-Xclang', result)


def print_active_checkers(checkers):
    """ Print active checkers to stdout. """

    for name in sorted(name for name, (_, active) in checkers.items()
                       if active):
        print(name)


def print_checkers(checkers):
    """ Print verbose checker help to stdout. """

    print('')
    print('available checkers:')
    print('')
    for name in sorted(checkers.keys()):
        description, active = checkers[name]
        prefix = '+' if active else ' '
        if len(name) > 30:
            print(' {0} {1}'.format(prefix, name))
            print(' ' * 35 + description)
        else:
            print(' {0} {1: <30}  {2}'.format(prefix, name, description))
    print('')
    print('NOTE: "+" indicates that an analysis is enabled by default.')
    print('')


def validate(parser, args, from_build_command):
    """ Validation done by the parser itself, but semantic check still
    needs to be done. This method is doing that. """

    # Make plugins always a list. (It might be None when not specified.)
    args.plugins = args.plugins if args.plugins else []

    if args.help_checkers_verbose:
        print_checkers(get_checkers(args.clang, args.plugins))
        parser.exit()
    elif args.help_checkers:
        print_active_checkers(get_checkers(args.clang, args.plugins))
        parser.exit()

    if from_build_command and not args.build:
        parser.error('missing build command')


def create_parser(from_build_command):
    """ Command line argument parser factory method. """

    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument(
        '--verbose', '-v',
        action='count',
        default=0,
        help="""Enable verbose output from '%(prog)s'. A second and third
                flag increases verbosity.""")
    parser.add_argument(
        '--override-compiler',
        action='store_true',
        help="""Always resort to the compiler wrapper even when better
                interposition methods are available.""")
    parser.add_argument(
        '--intercept-first',
        action='store_true',
        help="""Run the build commands only, build a compilation database,
                then run the static analyzer afterwards.
                Generally speaking it has better coverage on build commands.
                With '--override-compiler' it use compiler wrapper, but does
                not run the analyzer till the build is finished. """)
    parser.add_argument(
        '--cdb',
        metavar='<file>',
        default="compile_commands.json",
        help="""The JSON compilation database.""")

    parser.add_argument(
        '--output', '-o',
        metavar='<path>',
        default=tempdir(),
        help="""Specifies the output directory for analyzer reports.
                Subdirectory will be created if default directory is targeted.
                """)
    parser.add_argument(
        '--status-bugs',
        action='store_true',
        help="""By default, the exit status of '%(prog)s' is the same as the
                executed build command. Specifying this option causes the exit
                status of '%(prog)s' to be non zero if it found potential bugs
                and zero otherwise.""")
    parser.add_argument(
        '--html-title',
        metavar='<title>',
        help="""Specify the title used on generated HTML pages.
                If not specified, a default title will be used.""")
    parser.add_argument(
        '--analyze-headers',
        action='store_true',
        help="""Also analyze functions in #included files. By default, such
                functions are skipped unless they are called by functions
                within the main source file.""")
    format_group = parser.add_mutually_exclusive_group()
    format_group.add_argument(
        '--plist', '-plist',
        dest='output_format',
        const='plist',
        default='html',
        action='store_const',
        help="""This option outputs the results as a set of .plist files.""")
    format_group.add_argument(
        '--plist-html', '-plist-html',
        dest='output_format',
        const='plist-html',
        default='html',
        action='store_const',
        help="""This option outputs the results as a set of .html and .plist
                files.""")
    # TODO: implement '-view '

    advanced = parser.add_argument_group('advanced options')
    advanced.add_argument(
        '--keep-empty',
        action='store_true',
        help="""Don't remove the build results directory even if no issues
                were reported.""")
    advanced.add_argument(
        '--no-failure-reports', '-no-failure-reports',
        dest='output_failures',
        action='store_false',
        help="""Do not create a 'failures' subdirectory that includes analyzer
                crash reports and preprocessed source files.""")
    advanced.add_argument(
        '--stats', '-stats',
        action='store_true',
        help="""Generates visitation statistics for the project being analyzed.
                """)
    advanced.add_argument(
        '--internal-stats',
        action='store_true',
        help="""Generate internal analyzer statistics.""")
    advanced.add_argument(
        '--maxloop', '-maxloop',
        metavar='<loop count>',
        type=int,
        help="""Specifiy the number of times a block can be visited before
                giving up. Increase for more comprehensive coverage at a cost
                of speed.""")
    advanced.add_argument(
        '--store', '-store',
        metavar='<model>',
        dest='store_model',
        choices=['region', 'basic'],
        help="""Specify the store model used by the analyzer.
                'region' specifies a field- sensitive store model.
                'basic' which is far less precise but can more quickly
                analyze code. 'basic' was the default store model for
                checker-0.221 and earlier.""")
    advanced.add_argument(
        '--constraints', '-constraints',
        metavar='<model>',
        dest='constraints_model',
        choices=['range', 'basic'],
        help="""Specify the contraint engine used by the analyzer. Specifying
                'basic' uses a simpler, less powerful constraint model used by
                checker-0.160 and earlier.""")
    advanced.add_argument(
        '--use-analyzer',
        metavar='<path>',
        dest='clang',
        default='clang',
        help="""'%(prog)s' uses the 'clang' executable relative to itself for
                static analysis. One can override this behavior with this
                option by using the 'clang' packaged with Xcode (on OS X) or
                from the PATH.""")
    advanced.add_argument(
        '--use-cc',
        metavar='<path>',
        dest='cc',
        default='cc',
        help="""When '%(prog)s' analyzes a project by interposing a "fake
                compiler", which executes a real compiler for compilation and
                do other tasks (to run the static analyzer or just record the
                compiler invocation). Because of this interposing, '%(prog)s'
                does not know what compiler your project normally uses.
                Instead, it simply overrides the CC environment variable, and
                guesses your default compiler.

                If you need '%(prog)s' to use a specific compiler for
                *compilation* then you can use this option to specify a path
                to that compiler.""")
    advanced.add_argument(
        '--use-c++',
        metavar='<path>',
        dest='cxx',
        default='c++',
        help="""This is the same as "--use-cc" but for C++ code.""")
    advanced.add_argument(
        '--analyzer-config', '-analyzer-config',
        metavar='<options>',
        help="""Provide options to pass through to the analyzer's
                -analyzer-config flag. Several options are separated with
                comma: 'key1=val1,key2=val2'

                Available options:
                    stable-report-filename=true or false (default)

                Switch the page naming to:
                report-<filename>-<function/method name>-<id>.html
                instead of report-XXXXXX.html""")
    advanced.add_argument(
        '--exclude',
        metavar='<directory>',
        dest='excludes',
        action='append',
        default=[],
        help="""Do not run static analyzer against files found in this
                directory. (You can specify this option multiple times.)
                Could be usefull when project contains 3rd party libraries.
                The directory path shall be absolute path as file names in
                the compilation database.""")
    advanced.add_argument(
        '--force-analyze-debug-code',
        dest='force_debug',
        action='store_true',
        help="""Tells analyzer to enable assertions in code even if they were
                disabled during compilation, enabling more precise results.""")

    plugins = parser.add_argument_group('checker options')
    plugins.add_argument(
        '--load-plugin', '-load-plugin',
        metavar='<plugin library>',
        dest='plugins',
        action='append',
        help="""Loading external checkers using the clang plugin interface.""")
    plugins.add_argument(
        '--enable-checker', '-enable-checker',
        metavar='<checker name>',
        action=AppendCommaSeparated,
        help="""Enable specific checker.""")
    plugins.add_argument(
        '--disable-checker', '-disable-checker',
        metavar='<checker name>',
        action=AppendCommaSeparated,
        help="""Disable specific checker.""")
    plugins.add_argument(
        '--help-checkers',
        action='store_true',
        help="""A default group of checkers is run unless explicitly disabled.
                Exactly which checkers constitute the default group is a
                function of the operating system in use. These can be printed
                with this flag.""")
    plugins.add_argument(
        '--help-checkers-verbose',
        action='store_true',
        help="""Print all available checkers and mark the enabled ones.""")

    if from_build_command:
        parser.add_argument(
            dest='build',
            nargs=argparse.REMAINDER,
            help="""Command to run.""")

    return parser


class AppendCommaSeparated(argparse.Action):
    """ argparse Action class to support multiple comma separated lists. """

    def __call__(self, __parser, namespace, values, __option_string):
        # getattr(obj, attr, default) does not really returns default but none
        if getattr(namespace, self.dest, None) is None:
            setattr(namespace, self.dest, [])
        # once it's fixed we can use as expected
        actual = getattr(namespace, self.dest)
        actual.extend(values.split(','))
        setattr(namespace, self.dest, actual)
