# -*- coding: utf-8 -*-
__author__ = 'eternnoir'

import os
from subprocess import Popen, PIPE

SOURCEANALYZERBIN = 'sourceanalyzer'


class FortifySCA(object):
    def __init__(self, bin_path=SOURCEANALYZERBIN, min_mem=400, max_mem=2048, vs_version='10.0', debug=False):
        self.vs_version = vs_version
        self.max_mem = max_mem
        self.min_mem = min_mem
        self.bin_path = bin_path
        self.debug = debug

    def scan(self, build_id, path, output_frp, pdf_filename=None, need_clean=True):
        self.__check_sca_bin__()
        if need_clean:
            r, output = self.clean(build_id, path)
            if not r:
                self.__print__(output)
                raise Exception("Clean Fail.")

        r, output = self.translating(build_id, path)
        self.__print__(output)
        if not r:
            raise Exception("Transtating Fail.")

        command = [self.bin_path, self.__build_max_memory_command__(), self.__build_min_memory_command__(),
                   '-vsversion', self.vs_version, '-b', build_id, '-scan',
                   '-f', output_frp]
        p = Popen(command, stdout=PIPE, stderr=PIPE, cwd=path)
        output, err = p.communicate()
        if p.returncode != 0:
            return False, output
        return True, output

    def translating(self, build_id, path):
        command = [self.bin_path, self.__build_max_memory_command__(), self.__build_min_memory_command__(),
                   '-vsversion', self.vs_version, '-b', build_id, os.path.abspath(path)]
        p = Popen(command, stdout=PIPE, stderr=PIPE, cwd=path)
        output, err = p.communicate()
        if p.returncode != 0:
            return False, output
        return True, output

    def clean(self, build_id, path):
        command = [self.bin_path, self.__build_max_memory_command__(), self.__build_min_memory_command__(),
                   '-vsversion', self.vs_version, '-b', build_id, '-clean']
        p = Popen(command, stdout=PIPE, stderr=PIPE, cwd=path)
        output, err = p.communicate()
        if p.returncode != 0:
            return False, output
        return True, output

    def __check_parama__(self):
        if not self.__check_sca_bin__():
            raise Exception('SCA bin sourceanalyzer not found.')

    def __check_sca_bin__(self):
        command = [self.bin_path, '-h']
        p = Popen(command, stdout=PIPE, stderr=PIPE)
        output, err = p.communicate()
        if p.returncode != 0:
            print(output)
            return False

    def __build_max_memory_command__(self):
        return "-Xmx" + str(self.max_mem) + "M"

    def __build_min_memory_command__(self):
        return "-Xms" + str(self.min_mem) + "M"

    def __print__(self, message):
        if self.debug:
            print(message)

@@ -506,16 +506,32 @@
 ean=True
+, load_dlls=True
 ):%0A     
@@ -581,16 +581,59 @@
 _clean:%0A
+            self.__print__(%22Start Clean.%22)%0A
         
@@ -776,32 +776,175 @@
 %22Clean Fail.%22)%0A%0A
+        dll_args = %5B%5D%0A        if load_dlls:%0A            dll_args = self.__build_dll_args__(path)%0A%0A        self.__print__(%22Start Translating.%22)%0A
         r, outpu
@@ -970,32 +970,47 @@
 g(build_id, path
+, args=dll_args
 )%0A        self._
@@ -1086,32 +1086,70 @@
 tating Fail.%22)%0A%0A
+        self.__print__(%22Start Scan.%22)%0A
         command 
@@ -1577,32 +1577,41 @@
 , build_id, path
+, args=%5B%5D
 ):%0A        comma
@@ -1794,16 +1794,73 @@
 (path)%5D%0A
+        for arg in args:%0A            command.append(arg)%0A
         
@@ -3043,78 +3043,668 @@
 f __
-print__(self, message):%0A        if self.debug:%0A            print(message)%0A
+build_dll_args__(self, folder_path):%0A        ret = %5B%22-libdirs%22%5D%0A        dll_list = get_all_dll_path(folder_path)%0A        if len(dll_list) == 0:%0A            return %5B%5D%0A%0A        dll_path_string = %22%22%0A        for dll_path in dll_list:%0A            dll_path_string += dll_path + %22;%22%0A%0A        ret.append(dll_path_string)%0A        return ret%0A%0A    def __print__(self, message):%0A        if self.debug:%0A            print(message)%0A%0A%0Adef get_all_dll_path(folder_path):%0A    ret = %5B%5D%0A    import os%0A    for root, dirs, files in os.walk(folder_path):%0A        for file in files:%0A            if file.endswith(%22.dll%22):%0A                ret.append(os.path.join(root, file))%0A    return ret

Add some debug info.