"""This script contains various utility functions."""

import time
import cProfile
import pstats
import io
from urllib import parse
from functools import wraps
from bs4 import BeautifulSoup

from .settings import DICTS


def make_a_soup(text):
    soup = BeautifulSoup(text, "lxml")
    return soup


def replace_all(string):
    return (
        string.replace("\n            (", "(")
        .replace("(\n    \t                ", "(")
        .replace("\n", " ")
        .replace("      \t                ", " ")
        .replace("\\'", "'")
        .replace("  ", " ")
        .replace("\xa0 ", "")
        .replace("[ ", "")
        .replace(" ]", "")
        .replace("[", "")
        .replace("]", "")
        .replace("A1", "")
        .replace("A2", "")
        .replace("B1", "")
        .replace("B2", "")
        .replace("C1", "")
        .replace("C2", "")
        .strip()
    )


def parse_response_url(url):
    """Return the unquoted Cambridge url for displaying and saving."""

    response_base_url = url.split("?")[0]
    return response_base_url


def get_request_url(url, input_word, dict):
    """Return the url formatted to request the web page."""

    if dict == DICTS.CAMBRIDGE.name:
        query_word = input_word.replace(" ", "-").replace("/", "-")
        request_url = url + query_word
        return request_url

    return url + parse.quote(input_word)


def get_request_url_spellcheck(url, input_word):
    """Return the url formatted to request Cambridge spellcheck web page."""

    query_word = input_word.replace(" ", "+").replace("/", "+")
    request_url = url + query_word

    return request_url


def decode_url(url):
    return parse.unquote(url)


def profile(func):
    """A decorator that uses cProfile to profile a function"""

    def inner(*args, **kwargs):
        pr = cProfile.Profile()
        pr.enable()
        retval = func(*args, **kwargs)
        pr.disable()
        s = io.StringIO()
        sortby = "cumulative"
        ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
        ps.print_stats()
        print(s.getvalue())
        return retval

    return inner


def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_at = time.time()
        f = func(*args, **kwargs)
        time_taken = round((time.time() - start_at), 2)
        print("\nTime taken: {} seconds".format(time_taken))
        return f

    return wrapper
