# -*- coding: utf-8 -*-
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
""" This module is responsible for the Clang executable.

Since Clang command line interface is so rich, but this project is using only
a subset of that, it makes sense to create a function specific wrapper. """

import subprocess
import re
from libscanbuild import run_command
from libscanbuild.shell import decode

__all__ = ['get_version', 'get_arguments', 'get_checkers', 'is_ctu_capable',
           'get_triple_arch']

# regex for activated checker
ACTIVE_CHECKER_PATTERN = re.compile(r'^-analyzer-checker=(.*)$')


def get_version(clang):
    """ Returns the compiler version as string.

    :param clang:   the compiler we are using
    :return:        the version string printed to stderr """

    output = run_command([clang, '-v'])
    # the relevant version info is in the first line
    return output[0]


def get_arguments(command, cwd):
    """ Capture Clang invocation.

    :param command: the compilation command
    :param cwd:     the current working directory
    :return:        the detailed front-end invocation command """

    cmd = command[:]
    cmd.insert(1, '-###')

    output = run_command(cmd, cwd=cwd)
    # The relevant information is in the last line of the output.
    # Don't check if finding last line fails, would throw exception anyway.
    last_line = output[-1]
    if re.search(r'clang(.*): error:', last_line):
        raise Exception(last_line)
    return decode(last_line)


def get_active_checkers(clang, plugins):
    """ Get the active checker list.

    :param clang:   the compiler we are using
    :param plugins: list of plugins which was requested by the user
    :return:        list of checker names which are active

    To get the default checkers we execute Clang to print how this
    compilation would be called. And take out the enabled checker from the
    arguments. For input file we specify stdin and pass only language
    information. """

    def get_active_checkers_for(language):
        """ Returns a list of active checkers for the given language. """

        load_args = [arg
                     for plugin in plugins
                     for arg in ['-Xclang', '-load', '-Xclang', plugin]]
        cmd = [clang, '--analyze'] + load_args + ['-x', language, '-']
        return [ACTIVE_CHECKER_PATTERN.match(arg).group(1)
                for arg in get_arguments(cmd, '.')
                if ACTIVE_CHECKER_PATTERN.match(arg)]

    result = set()
    for language in ['c', 'c++', 'objective-c', 'objective-c++']:
        result.update(get_active_checkers_for(language))
    return frozenset(result)


def is_active(checkers):
    """ Returns a method, which classifies the checker active or not,
    based on the received checker name list. """

    def predicate(checker):
        """ Returns True if the given checker is active. """

        return any(pattern.match(checker) for pattern in predicate.patterns)

    predicate.patterns = [re.compile(r'^' + a + r'(\.|$)') for a in checkers]
    return predicate


def parse_checkers(stream):
    """ Parse clang -analyzer-checker-help output.

    Below the line 'CHECKERS:' are there the name description pairs.
    Many of them are in one line, but some long named checker has the
    name and the description in separate lines.

    The checker name is always prefixed with two space character. The
    name contains no whitespaces. Then followed by newline (if it's
    too long) or other space characters comes the description of the
    checker. The description ends with a newline character.

    :param stream:  list of lines to parse
    :return:        generator of tuples

    (<checker name>, <checker description>) """

    lines = iter(stream)
    # find checkers header
    for line in lines:
        if re.match(r'^CHECKERS:', line):
            break
    # find entries
    state = None
    for line in lines:
        if state and not re.match(r'^\s\s\S', line):
            yield (state, line.strip())
            state = None
        elif re.match(r'^\s\s\S+$', line.rstrip()):
            state = line.strip()
        else:
            pattern = re.compile(r'^\s\s(?P<key>\S*)\s*(?P<value>.*)')
            match = pattern.match(line.rstrip())
            if match:
                current = match.groupdict()
                yield (current['key'], current['value'])


def get_checkers(clang, plugins):
    """ Get all the available checkers from default and from the plugins.

    :param clang:   the compiler we are using
    :param plugins: list of plugins which was requested by the user
    :return:        a dictionary of all available checkers and its status

    {<checker name>: (<checker description>, <is active by default>)} """

    load = [elem for plugin in plugins for elem in ['-load', plugin]]
    cmd = [clang, '-cc1'] + load + ['-analyzer-checker-help']

    lines = run_command(cmd)

    is_active_checker = is_active(get_active_checkers(clang, plugins))

    checkers = {
        name: (description, is_active_checker(name))
        for name, description in parse_checkers(lines)
    }
    if not checkers:
        raise Exception('Could not query Clang for available checkers.')

    return checkers


def is_ctu_capable(extdef_map_cmd):
    """ Detects if the current (or given) clang and external definition mapping
    executables are CTU compatible. """

    try:
        run_command([extdef_map_cmd, '-version'])
    except (OSError, subprocess.CalledProcessError):
        return False
    return True


def get_triple_arch(command, cwd):
    """Returns the architecture part of the target triple for the given
    compilation command. """

    cmd = get_arguments(command, cwd)
    try:
        separator = cmd.index("-triple")
        return cmd[separator + 1]
    except (IndexError, ValueError):
        return ""
