import json
import logging
from time import sleep
import sys
from datetime import datetime
import hashlib
from typing import Union


logger = logging.getLogger(__name__)


def process_browser_log_entry(entry):
    """Принимаем даннаые из performance и возвращаем json"""
    response = json.loads(entry['message'])['message']
    return response


def check_requests(driver):
    # TODO: add FireFox
    """
    Функция смотрит в DevTools Chrome в раздел Network.
    Если у запроса ответ не 200 или 204, кладет в лог урл и статус
    """
    if driver.capabilities["browserName"] == "chrome":
        statuses = [200, 204, 304]
        for performance_data in driver.get_log('performance'):
            requests_json = process_browser_log_entry(performance_data)
            if requests_json["method"] == "Network.responseReceived":
                if requests_json["params"]["response"]["status"] in statuses:
                    pass
                else:
                    logger.error("Request Url: %s, status - %s",
                                 requests_json["params"]["response"]["url"],
                                 requests_json["params"]["response"]["status"])


def notifies_needed():
    """Функция, проверяющая аргументы на наличие --send-notifies (активация отправки уведомлений в ТГ)"""
    if '--send-notifies' in sys.argv:
        logger.info("Notifies are enabled!")
        return True
    else:
        logger.info("Notifies are disabled!")
        return False


def screencast_needed():
    """Функция, проверяющая аргументы на наличие --screencast (запись скринкаста)"""
    if '--screencast' in sys.argv:
        logger.info("Screencast is enabled!")
        return True
    else:
        logger.info("Screencast is disabled!")
        return False


def get_response_data(driver, url: str, wait: int = None):
    # TODO: add FireFox
    """Функция для логгирования ответа от эндпойнта, url которого передаем аргументом"""
    if driver.capabilities["browserName"] == "chrome":
        logger.info("Try to get response data for endpoint %s", url)
        if wait:
            sleep(wait)
        browser_log = driver.get_log('performance')
        events = [process_browser_log_entry(entry) for entry in browser_log]
        events = [event for event in events if 'Network.response' in event['method']]
        tmp_event_list = []
        event_list = []
        for event in events:
            try:
                event_type = event['params']['type']
            except Exception:
                event_type = 'None'
            if event_type == 'XHR':
                tmp_event_list.append(event)
        for event in tmp_event_list:
            try:
                event_url = event['params']['response']['url']
            except Exception:
                event_url = "None"
            if url == event_url:
                event_list.append(event)

        if len(event_list) > 0:
            for i in range(len(event_list)):
                response = driver.execute_cdp_cmd('Network.getResponseBody',
                                                  {'requestId': event_list[i]["params"]["requestId"]})
                logger.info("Endpoint's %s response: %s", url, response['body'])
        else:
            logger.error("Responses list is empty")


def get_datetime():
    now = datetime.now()
    logger.info("Fixed datetime: %s", now)
    return now


def get_timediff(start_time: datetime, end_time: datetime):
    time_diff = end_time - start_time
    logger.info("Time diff: %s", time_diff)
    return time_diff


def get_used_memory(driver):
    # TODO: add FireFox
    """Смотрим в консоли, сколько памяти загрузил в себя js"""
    if driver.capabilities["browserName"] == "chrome":
        return driver.execute_script("""var mem = window.performance.memory.usedJSHeapSize /  1048576; return mem;""")
    else:
        return None


def to_hash(data: str, algorithm: Union[str, bytes]):
    """Вычисление хэша данных с указанием алгоритма при помощи библиотеки hashlib."""
    try:
        hash_generator = getattr(hashlib, algorithm)()
    except AttributeError:
        raise AttributeError("Not supported algorithm. Supported only: sha1, sha256, sha512")

    hash_generator.update(data.encode())
    return hash_generator.hexdigest()
