# -*- coding: utf-8 -*-

"""
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Development Team: Brain Storm Team
"""
from src.core import helper
from src.core import sys
from src.core.http.providers.debug import DebugProvider
from src.lib.tpl import Tpl as tpl


class Debug(DebugProvider):
    """Debug class"""

    def __init__(self, Config):
        """
        Debug constructor.

        :param Config: Config
        """

        self.__catched = False
        self.__clear = False
        self.__cfg = Config
        self.__level = self.__cfg.debug

        if self.__level > 0:
            tpl.debug(key='debug', level=self.__cfg.debug, method=self.__cfg.method)

    @property
    def level(self):
        """Get debug level."""

        return self.__level

    def debug_user_agents(self):
        """Debug info for user agent."""

        if self.__level > 0:
            if self.__cfg.is_random_user_agent is True:
                tpl.debug(key='random_browser')
            else:
                tpl.debug(key='browser', browser=self.__cfg.user_agent)

        return True

    def debug_list(self, total_lines):
        """Debug scan list."""

        if self.__level > 0:
            if self.__cfg.is_random_list is True:
                tpl.debug(key='randomizing')
            if self.__cfg.DEFAULT_SCAN == self.__cfg.scan:
                if self.__cfg.is_extension_filter is True:
                    tpl.debug(key='ext_filter', total=total_lines, ext=', '.join(self.__cfg.extensions))
                elif self.__cfg.is_ignore_extension_filter is True:
                    tpl.debug(key='ext_ignore_filter', total=total_lines, ext=', '.join(self.__cfg.ignore_extensions))
                else:
                    tpl.debug(key='directories', total=total_lines)
            else:
                tpl.debug(key='subdomains', total=total_lines)
            tpl.debug(key='create_queue', threads=self.__cfg.threads)

        return True

    def debug_connection_pool(self, keymsg, pool, connection_type):
        """Debug connection pool message."""

        tpl.debug(key=keymsg, type=connection_type)
        if pool:
            tpl.debug(str(pool), type=connection_type)

        return True

    def debug_header_bypass(self):
        """Debug header-bypass configuration."""

        if self.__level > 0 and self.__cfg.is_header_bypass is True:
            tpl.debug(
                key='header_bypass_enabled',
                statuses=','.join([str(status) for status in self.__cfg.header_bypass_status]),
                limit=self.__cfg.header_bypass_limit,
                headers=len(self.__cfg.header_bypass_headers)
            )

        return True

    def debug_proxy_pool(self):
        """Debug proxy pool message."""

        if self.__cfg.is_external_proxy_list is True:
            tpl.debug(key='proxy_pool_external_start')
        elif self.__cfg.is_standalone_proxy is True:
            tpl.debug(key='proxy_pool_standalone', server=self.__cfg.proxy)
        elif self.__cfg.is_builtin_proxy_pool is True:
            tpl.debug(key='proxy_pool_internal_start')

        return True

    def debug_request(self, request_header, url, method):
        """Debug request."""

        if not isinstance(request_header, dict):
            request_header = request_header.__dict__

        request_data = dict(request_header)
        request_data.update({'Request URI': url, 'Request Method': method})

        tpl.debug(key='request_header_dbg', dbg=helper.to_json(request_data))

        return True

    def debug_response(self, response_header):
        """Debug response."""

        tpl.debug(key='response_header_dbg', dbg=helper.to_json(response_header))

        return True

    def debug_request_uri(self, status, request_uri, **kwargs):
        """Debug request_uri."""

        percentage = tpl.line(msg=helper.percent(kwargs.get('items_size', 0), kwargs.get('total_size', 1)), color='cyan')
        total_len = len(str(abs(kwargs.get('total_size', 1))))

        if self.__cfg.DEFAULT_SCAN == self.__cfg.scan:
            urlpath = helper.parse_url(request_uri).path
        else:
            urlpath = request_uri

        if status in ['success', 'file', 'indexof', 'certificate', 'auth']:
            request_uri = tpl.line(key=status, color='green', url=urlpath)
        elif status in ['bad', 'forbidden']:
            request_uri = tpl.line(key='forbidden', color='yellow', url=urlpath)
        elif status in ['redirect']:
            request_uri = tpl.line(key='redirect', color='blue', url=urlpath, rurl=kwargs.get('redirect_uri'))
        elif status in ['blocked']:
            waf_name = kwargs.get('waf_name')
            waf_confidence = kwargs.get('waf_confidence')

            if waf_name:
                request_uri = tpl.line(
                    msg='WAF: {0} ({1}%) {2}'.format(waf_name, waf_confidence, urlpath),
                    color='yellow'
                )
            else:
                request_uri = tpl.line(key=status, color='yellow', url=urlpath)

        self.__clear = True if self.__catched else False

        if status in ['success', 'file', 'bad', 'forbidden', 'redirect', 'blocked', 'indexof', 'certificate', 'auth']:
            sys.writels('', flush=True)
            tpl.info(
                key='get_item',
                clear=self.__clear,
                percent=percentage,
                current='{0:0{l}d}'.format(kwargs.get('items_size', 0), l=total_len),
                total=kwargs.get('total_size', 1),
                item=request_uri,
                size=kwargs.get('content_size'),
                code=kwargs.get('response_code', '-'),
            )
            self.__catched = True
        else:
            request_uri = tpl.line(
                msg=urlpath,
                color='white'
            )

            if self.__level != -1:
                tpl.line_log(
                    key='get_item',
                    percent=percentage,
                    current='{0:0{l}d}'.format(kwargs.get('items_size', 0), l=total_len),
                    total=kwargs.get('total_size', 1),
                    item=request_uri,
                    size=kwargs.get('content_size'),
                    code=kwargs.get('response_code', '-'),
                )

            self.__catched = False
            if kwargs.get('items_size', 0) == kwargs.get('total_size', 1):
                sys.writels('', flush=True)

        return True

    def debug_load_sniffer_plugin(self, description):
        """Debug load sniffers plugin."""

        tpl.debug(key='load_sniffer_plugin', description=description)

        return True