# -*- 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 parses and validates arguments for command-line interfaces.

It uses argparse module to create the command line parser. (This library is
in the standard python library since 3.2 and backported to 2.7, but not
earlier.)

It also implements basic validation methods, related to the command.
Validations are mostly calling specific help methods, or mangling values.
"""

import os
import sys
import argparse
import logging
import tempfile
from libscanbuild import reconfigure_logging
from libscanbuild.clang import get_checkers

__all__ = ['parse_args_for_intercept_build', 'parse_args_for_analyze_build',
           'parse_args_for_scan_build']


def parse_args_for_intercept_build():
    """ Parse and validate command-line arguments for intercept-build. """

    parser = create_intercept_parser()
    args = parser.parse_args()

    reconfigure_logging(args.verbose)
    logging.debug('Raw arguments %s', sys.argv)

    # short validation logic
    if not args.build:
        parser.error(message='missing build command')

    logging.debug('Parsed arguments: %s', args)
    return args


def parse_args_for_analyze_build():
    """ Parse and validate command-line arguments for analyze-build. """

    from_build_command = False
    parser = create_analyze_parser(from_build_command)
    args = parser.parse_args()

    reconfigure_logging(args.verbose)
    logging.debug('Raw arguments %s', sys.argv)

    normalize_args_for_analyze(args, from_build_command)
    validate_args_for_analyze(parser, args, from_build_command)
    logging.debug('Parsed arguments: %s', args)
    return args


def parse_args_for_scan_build():
    """ Parse and validate command-line arguments for scan-build. """

    from_build_command = True
    parser = create_analyze_parser(from_build_command)
    args = parser.parse_args()

    reconfigure_logging(args.verbose)
    logging.debug('Raw arguments %s', sys.argv)

    normalize_args_for_analyze(args, from_build_command)
    validate_args_for_analyze(parser, args, from_build_command)
    logging.debug('Parsed arguments: %s', args)
    return args


def normalize_args_for_analyze(args, from_build_command):
    """ Normalize parsed arguments for analyze-build and scan-build.

    :param args: Parsed argument object. (Will be mutated.)
    :param from_build_command: Boolean value tells is the command suppose
    to run the analyzer against a build command or a compilation db. """

    # make plugins always a list. (it might be None when not specified.)
    if args.plugins is None:
        args.plugins = []

    # make exclude directory list unique and absolute.
    uniq_excludes = set(os.path.abspath(entry) for entry in args.excludes)
    args.excludes = list(uniq_excludes)

    # because shared codes for all tools, some common used methods are
    # expecting some argument to be present. so, instead of query the args
    # object about the presence of the flag, we fake it here. to make those
    # methods more readable. (it's an arguable choice, took it only for those
    # which have good default value.)
    if from_build_command:
        # add cdb parameter invisibly to make report module working.
        args.cdb = 'compile_commands.json'


def validate_args_for_analyze(parser, args, from_build_command):
    """ Command line parsing is done by the argparse module, but semantic
    validation still needs to be done. This method is doing it for
    analyze-build and scan-build commands.

    :param parser: The command line parser object.
    :param args: Parsed argument object.
    :param from_build_command: Boolean value tells is the command suppose
    to run the analyzer against a build command or a compilation db.
    :return: No return value, but this call might throw when validation
    fails. """

    if args.help_checkers_verbose:
        print_checkers(get_checkers(args.clang, args.plugins))
        parser.exit(status=0)
    elif args.help_checkers:
        print_active_checkers(get_checkers(args.clang, args.plugins))
        parser.exit(status=0)
    elif from_build_command and not args.build:
        parser.error(message='missing build command')
    elif not from_build_command and not os.path.exists(args.cdb):
        parser.error(message='compilation database is missing')


def create_intercept_parser():
    """ Creates a parser for command-line arguments to 'intercept'. """

    parser = create_default_parser()
    parser_add_cdb(parser)

    parser_add_prefer_wrapper(parser)
    parser_add_compilers(parser)

    advanced = parser.add_argument_group('advanced options')
    group = advanced.add_mutually_exclusive_group()
    group.add_argument(
        '--append',
        action='store_true',
        help="""Extend existing compilation database with new entries.
        Duplicate entries are detected and not present in the final output.
        The output is not continuously updated, it's done when the build
        command finished. """)

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


def create_analyze_parser(from_build_command):
    """ Creates a parser for command-line arguments to 'analyze'. """

    parser = create_default_parser()

    if from_build_command:
        parser_add_prefer_wrapper(parser)
        parser_add_compilers(parser)

        parser.add_argument(
            '--intercept-first',
            action='store_true',
            help="""Run the build commands first, intercept compiler
            calls and 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.""")
    else:
        parser_add_cdb(parser)

    parser.add_argument(
        '--status-bugs',
        action='store_true',
        help="""The exit status of '%(prog)s' is the same as the executed
        build command. This option ignores the build exit status and sets to
        be non zero if it found potential bugs or zero otherwise.""")
    parser.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 useful when project contains 3rd party libraries.""")

    output = parser.add_argument_group('output control options')
    output.add_argument(
        '--output',
        '-o',
        metavar='<path>',
        default=tempfile.gettempdir(),
        help="""Specifies the output directory for analyzer reports.
        Subdirectory will be created if default directory is targeted.""")
    output.add_argument(
        '--keep-empty',
        action='store_true',
        help="""Don't remove the build results directory even if no issues
        were reported.""")
    output.add_argument(
        '--html-title',
        metavar='<title>',
        help="""Specify the title used on generated HTML pages.
        If not specified, a default title will be used.""")
    format_group = output.add_mutually_exclusive_group()
    format_group.add_argument(
        '--plist',
        '-plist',
        dest='output_format',
        const='plist',
        default='html',
        action='store_const',
        help="""Cause 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="""Cause the results as a set of .html and .plist files.""")
    # TODO: implement '-view '

    advanced = parser.add_argument_group('advanced options')
    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(
        '--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.""")
    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.""")
    advanced.add_argument(
        '--stats',
        '-stats',
        action='store_true',
        help="""Generates visitation statistics for the project.""")
    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 constraint engine used by the analyzer. Specifying
        'basic' uses a simpler, less powerful constraint model used by
        checker-0.160 and earlier.""")
    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(
        '--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


def create_default_parser():
    """ Creates command line parser for all build wrapper commands. """

    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, third and
        fourth flags increases verbosity.""")
    return parser


def parser_add_cdb(parser):
    parser.add_argument(
        '--cdb',
        metavar='<file>',
        default="compile_commands.json",
        help="""The JSON compilation database.""")


def parser_add_prefer_wrapper(parser):
    parser.add_argument(
        '--override-compiler',
        action='store_true',
        help="""Always resort to the compiler wrapper even when better
        intercept methods are available.""")


def parser_add_compilers(parser):
    parser.add_argument(
        '--use-cc',
        metavar='<path>',
        dest='cc',
        default=os.getenv('CC', 'cc'),
        help="""When '%(prog)s' analyzes a project by interposing a compiler
        wrapper, which executes a real compiler for compilation and do other
        tasks (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.""")
    parser.add_argument(
        '--use-c++',
        metavar='<path>',
        dest='cxx',
        default=os.getenv('CXX', 'c++'),
        help="""This is the same as "--use-cc" but for C++ code.""")


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)


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('')
