# Copyright (c) 2015-present, Facebook, Inc.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import logging
import os

from . import util
from inferlib import jwlib

MODULE_NAME = __name__
MODULE_DESCRIPTION = '''Run analysis of code built with a command like:
ant [options] [target]

Analysis examples:
infer -- ant compile'''
LANG = ['java']


def gen_instance(*args):
    return AntCapture(*args)


# This creates an empty argparser for the module, which provides only
# description/usage information and no arguments.
create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME)


class AntCapture:

    def __init__(self, args, cmd):
        self.args = args
        util.log_java_version()
        logging.info(util.run_cmd_ignore_fail([cmd[0], '-version']))
        # TODO: make the extraction of targets smarter
        self.build_cmd = [cmd[0], '-verbose'] + cmd[1:]

    def is_interesting(self, content):
        return self.is_quoted(content) or content.endswith('.java')

    def is_quoted(self, argument):
        quote = '\''
        return len(argument) > 2 and argument[0] == quote\
            and argument[-1] == quote

    def remove_quotes(self, argument):
        if self.is_quoted(argument):
            return argument[1:-1]
        else:
            return argument

    def get_infer_commands(self, verbose_output):
        javac_pattern = '[javac]'
        argument_start_pattern = 'Compilation arguments'
        calls = []
        javac_arguments = []
        collect = False
        for line in verbose_output.split('\n'):
            if javac_pattern in line:
                if argument_start_pattern in line:
                    collect = True
                    if javac_arguments != []:
                        capture = jwlib.create_infer_command(javac_arguments)
                        calls.append(capture)
                        javac_arguments = []
                if collect:
                    pos = line.index(javac_pattern) + len(javac_pattern)
                    content = line[pos:].strip()
                    if self.is_interesting(content):
                        arg = self.remove_quotes(content)
                        javac_arguments.append(arg)
        if javac_arguments != []:
            capture = jwlib.create_infer_command(javac_arguments)
            calls.append(capture)
            javac_arguments = []
        return calls

    def capture(self):
        (code, (verbose_out, _)) = util.get_build_output(self.build_cmd)
        if code != os.EX_OK:
            return code
        cmds = self.get_infer_commands(verbose_out)
        return util.run_compilation_commands(cmds)