from __future__ import annotations
from .codeanalysis import _CodeAnalysis
from ...logger import _logger
from ...out import GreppedOut


class MalwareBehaviour(_CodeAnalysis):
    """
    This class is used to identify various behaviours that can be normal, 
    but often displayed by malware. This class inherits from the 
    _CodeAnalysis class directly, and is instantiated in the same 
    manner as the GlorifiedAndroid class. Any parameters that the GlorifiedAndroid class takes 
    can be passed to this class.

    :param str apk_path: Path to the APK
    :param str output_dir: Output dir for decompilation and unzipping, defaults to /tmp/GlorifiedAndroid
    :param str project_dir: Project directory used for already decompiled and processed apks, defaults to None
    :param bool json_output: Returns a Json object instead of dict. Defaults to False
    :param str rg_path: path to ripgrep. Defaults to looking for it in path
    :param str jadx_path: path to jadx. Defaults to looking for it in path
    :param bool clean_dir: delete the output directory before processing
    :raises NotValidPythonVersion: Raises if python version 3 is not used
    :raises DifferentAPKExists: Raises if decompiled APK is different than what is already decompiled
    :raises DependentBinaryMissing: Raises if ripgrep, or jadx is not found

    >>> from glorifiedgrep.android.modules.malware import MalwareBehaviour
    >>> m = MalwareBehaviour('/path/to/apk', output_dir='/out/dir')
    """

    @_logger
    def malware_take_screenshots(self, show_code: bool=False) -> GreppedOut:
        """
        Identify classes commonly used with taking screenshots

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_take_screenshots()
        """

        return self.code_screenshots(show_code=show_code)

    @_logger
    def malware_access_call_logs(self, show_code: bool=False) -> GreppedOut:
        """
        Identify classes commonly used with taking screenshots

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_access_call_logs()
        """

        return self.code_call_log(show_code=show_code)

    @_logger
    def malware_access_camera(self, show_code: bool=False) -> GreppedOut:
        """
        Identify classes commonly used with accessing the camera. 

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_access_camera()
        """

        return self.code_camera_access(show_code=show_code)

    @_logger
    def malware_get_external_storage(self, show_code: bool=False) -> GreppedOut:
        """
        Identify code that is commonly used to get path to the external 
        storage directory. 

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_get_external_storage()
        """

        return self.code_external_file_access(show_code=show_code)

    @_logger
    def malware_browser_db_access(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies code that accesses the browser db. This db usually 
        includes browsing history.  

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_browser_db_access()
        """

        return self.code_browser_db_access(show_code=show_code)

    @_logger
    def malware_database_query(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies code that queries any database on the device.   

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_database_query()
        """

        return self.code_database_query(show_code=show_code)

    @_logger
    def malware_boot_completed_persistance(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies if the application uses BOOT_COMPLETED action which is 
        typically used to start a service or a receiver on reboot. This indicates 
        persistance. 

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_boot_completed_persistance()
        """

        return self.code_boot_completed_persistance(show_code=show_code)

    @_logger
    def malware_download_files(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies if the application uses the DownloadManager class to 
        download files from onlines services. 

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_download_files()
        """

        return self.code_download_manager(show_code=show_code)

    @_logger
    def malware_accessibility_services(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies if the application uses varios classes and methods 
        related to accessibility services. Malware will often use this to 
        have a higher level control of the device.  

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_accessibility_services()
        """

        return self.code_accessibility_service(show_code=show_code)

    @_logger
    def malware_obtain_file_metadata(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies if he MediaStore class or some of its common 
        subclasses are being used by the app. These classes are used to get 
        media file metadata from both internal and external storage.  

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_obtain_file_metadata()
        """

        return self.code_mediastore(show_code=show_code)

    @_logger
    def malware_get_installed_packages(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies if the getInstalledPackages method from the PackageManager 
        class is being called. Malware will usually use this method to enumerate 
        all the installed apps in a device.

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_obtain_file_metadata()
        """

        return self.code_package_installed(show_code=show_code)

    @_logger
    def malware_debug(self, show_code: bool=False) -> GreppedOut:
        """
        Identifies if the app is either debuggable, or if it is 
        connected to a debugger. 

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> m.malware_debug()
        """

        debugger = self.code_debugger_check()
        debuggable = self.code_debuggable_check()
        return debuggable + debugger

    @_logger
    def malware_screen_unlock(self, show_code: bool=False) -> GreppedOut:
        """
        Find android.intent.action.USER_PRESENT in the manifest which 
        is usually an intent used to detect when the screen is unlocked. 
        The receiver for the intent should be inspected more closely.

        Parameters
        ----------
        show_code : bool, optional
            Show the full matched line, by default False

        Returns
        -------
        GreppedOut
            GreppedOut object

        Examples
        --------
        >>> a = GlorifiedAndroid('/path/to/apk')
        >>> a.malware_screen_unlock()
        """
        regex = r'android\.intent\.action\.USER_PRESENT'
        match = self._run_rg_and_process(regex=regex, code=show_code)
        self._code_analysis['malware_screen_unlock'] = match
        self.log_debug('')
        return match
