import ipaddress
import random
import requests
from urllib.parse import urlencode
from datetime import datetime, timedelta
from requests.structures import CaseInsensitiveDict
from .browser import Firefox
import string
import re

CIDRs = {}

CIDRs["us"] = [
    "68.121.80.248/30",
    "68.121.80.252/31",
    "68.121.80.255/32",

    "12.232.30.252/31",
    "12.232.30.255/32",
    "12.232.30.248/30",

    "47.189.48.255/32",
    "47.189.48.254/32",
    "47.189.48.248/30",

    "24.218.158.128/26",
    "24.218.158.128/26",
    "24.218.158.192/27",
]

CIDRs["sk"] = [
    "78.98.0.0/16",
    "78.99.0.0/17",
    "78.99.128.0/18",
    "78.99.192.0/19",

    "80.242.32.0/21",
    "80.242.40.0/22",
    "80.242.44.0/23",
    "80.242.46.0/24",

    "178.143.0.0/17",
    "178.143.128.0/18",
    "178.143.192.0/19",
    "178.143.224.0/20",

    "185.1.34.0/25",
    "185.1.34.128/26",
    "185.1.34.192/27",
    "185.1.34.224/28",
]

CIDRs["cz"] = [
    "103.119.108.0/25",
    "103.119.108.128/26",
    "103.119.108.192/27",
    "103.119.108.224/28",

    "109.235.0.0/22",
    "109.235.4.0/23",
    "109.235.6.0/24",
    "109.235.7.0/25",

    "130.193.8.0/21",
    "130.193.16.0/22",
    "130.193.20.0/23",
    "130.193.22.0/24",

    "152.89.75.128/26",
    "152.89.75.192/27",
    "152.89.75.224/28",
    "152.89.75.240/29",
]

def genIP(country=None):
    """
    Args:
        country (str): Abbr. of country to use, ex. US, CZ, case insensitive

    Returns:
        ip (str): Result ip is random
    """

    if not country:
        country = random.choice(get_simple_keys(CIDRs))

    CIDR = random.choice(CIDRs[country.lower()])
    ips = [str(ip) for ip in ipaddress.IPv4Network(CIDR)]
    return random.choice(ips)

# https://stackoverflow.com/questions/34327719/get-keys-from-json-in-python
def get_simple_keys(data):
    result = []
    for key in data.keys():
        if type(data[key]) != dict:
            result.append(key)
        else:
            result += get_simple_keys(data[key])
    return result

def randomString(length, upper=True, digits=True):
    s = string.ascii_lowercase
    if digits:
        s += string.digits
    if upper:
        s += string.ascii_uppercase
    return ''.join(random.choices(s, k=length))

def girc(page_data, url, co, key=""):
    """
    Code adapted from https://github.com/vb6rocod/utils/
    Copyright (C) 2019 vb6rocod
    and https://github.com/addon-lab/addon-lab_resolver_Project
    Copyright (C) 2021 ADDON-LAB, KAR10S
    """
    net = requests.Session()
    hdrs = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0",
            'Referer': url}
    rurl = 'https://www.google.com/recaptcha/api.js'
    aurl = 'https://www.google.com/recaptcha/api2'
    if not key:
        key = re.search(r'(?:src="{0}\?.*?render|data-sitekey)="?([^"]+)'.format(rurl), page_data)
        if key: key = key.group(1)
        
    if key:
        rurl = '{0}?render={1}'.format(rurl, key)
        page_data1 = net.get(rurl, headers=hdrs).text
        v = re.findall('releases/([^/]+)', page_data1)[0]
        rdata = {'ar': 1,
                 'k': key,
                 'co': co,
                 'hl': 'en',
                 'v': v,
                 'size': 'invisible',
                 'cb': '123456789'}
        page_data2 = net.get('{0}/anchor?{1}'.format(aurl, urlencode(rdata)), headers=hdrs).text
        rtoken = re.search('recaptcha-token.+?="([^"]+)', page_data2)
        if rtoken:
            rtoken = rtoken.group(1)
        else:
            return ''
        pdata = {'v': v,
                 'reason': 'q',
                 'k': key,
                 'c': rtoken,
                 'sa': '',
                 'co': co}
        hdrs.update({'Referer': aurl})
        page_data3 = net.post('{0}/reload?k={1}'.format(aurl, key), data=pdata, headers=hdrs).text
        gtoken = re.search('rresp","([^"]+)', page_data3)
        if gtoken:
            return gtoken.group(1)

    return ''

def getIP():
    return requests.get("https://api.my-ip.io/ip").text

def getCountry():
    data = requests.get(f"https://ipinfo.io/{getIP()}/json")
    return data.json()['country']

def image2text(image):
    expires = datetime.now() + timedelta(minutes=5)

    headers = {
        "accept": "application/json"
    }

    files = {
        'file': image,
        'expires': (None, expires.strftime("%Y-%m-%dT%H:%M:%S.000Z")),
        'maxDownloads': (None, '1'),
        'autoDelete': (None, 'true'),
    }

    response = requests.post('https://file.io/', headers=headers, files=files)

    firefox = Firefox()
    firefox.addHeader("Referer", "https://brandfolder.com")

    #html = requests.get("https://brandfolder.com/workbench/extract-text-from-image", headers=firefox.headers).text
    #KEY = re.findall(r"const BROWSER_GOOGLE_VISION_API_KEY ='(.*?)'", html, re.MULTILINE)[0]
    KEY = "AIzaSyAV-SXt0qiF5aHdn-Zgcl4Gr61_gxx28qs"

    apiResponse = requests.post(f"https://vision.googleapis.com/v1/images:annotate?key={KEY}", headers=firefox.headers, json={
        "requests": [{
            "features": [{
                "type": "DOCUMENT_TEXT_DETECTION"
            }],
            "image": {
                "source": {
                    "imageUri": response.json()['link']
                }
            }
        }]
    })
    try:
        return apiResponse.json()["responses"][0]["fullTextAnnotation"]["text"]
    except:
        return ""


def fakeIdentity(nat=""):
    data = requests.get(f"https://randomuser.me/api/?nat={nat}", headers=Firefox().headers)
    return data.json()["results"][0]


def wsidchk_solve(session, url):
    page_data = session.get(url).text
    if '<form id="wsidchk-form" style="display:none;" action="' not in page_data:
        return
    west = re.findall(r"west=(.*?),", page_data, re.DOTALL)[0]
    east = re.findall(r"east=(.*?),", page_data, re.DOTALL)[0]
    solved_url = re.findall(r'<form id="wsidchk-form" style="display:none;" action="(.*?)" method="get">', page_data)[0]

    headers = {
        'authority': 'onecompiler.com',
        'accept': '*/*',
        'accept-language': 'en-US,en;q=0.5',
        'authorization': 'Bearer undefined',
        'content-type': 'application/json',
        'origin': 'https://onecompiler.com',
        'referer': 'https://onecompiler.com/javascript/',
        'sec-ch-ua': '"Not/A)Brand";v="99", "Brave";v="115", "Chromium";v="115"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'sec-gpc': '1',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
    }

    json_data = {
        'name': 'JavaScript',
        'title': 'JavaScript Hello World',
        'version': 'ES6',
        'mode': 'javascript',
        'description': None,
        'extension': 'js',
        'languageType': 'programming',
        'active': True,
        'properties': {
            'language': 'javascript',
            'docs': True,
            'tutorials': True,
            'cheatsheets': True,
            'filesEditable': True,
            'filesDeletable': True,
            'files': [
                {
                    'name': 'index.js',
                    'content': f'var west={west};var east={east}; console.log(west+east);',
                },
            ],
            'newFileOptions': [
                {
                    'helpText': 'New JS file',
                    'name': 'script${i}.js',
                    'content': "/**\n *  In main file\n *  let script${i} = require('./script${i}');\n *  console.log(script${i}.sum(1, 2));\n */\n\nfunction sum(a, b) {\n    return a + b;\n}\n\nmodule.exports = { sum };",
                },
                {
                    'helpText': 'Add Dependencies',
                    'name': 'package.json',
                    'content': '{\n  "name": "main_app",\n  "version": "1.0.0",\n  "description": "",\n  "main": "HelloWorld.js",\n  "dependencies": {\n    "lodash": "^4.17.21"\n  }\n}',
                },
            ],
        },
        'visibility': 'public',
    }

    response = requests.post('https://onecompiler.com/api/code/exec', headers=headers, json=json_data)
    solution = response.json().get("stdout", "".strip())

    url = f"{url}{solved_url}?wsidchk={solution}".replace(" ", "")
    resp = session.get(url, allow_redirects=False)
    print(resp.cookies)
    print(resp.text)
    

    return solution


def generate_uuid4():
    # Generate 128 random bits
    random_bits = random.getrandbits(128)
    
    # Convert to a 32-character hex string
    hex_string = f'{random_bits:032x}'
    
    # Add the dashes in the proper places
    formatted_uuid = f"{hex_string[:8]}-{hex_string[8:12]}-{hex_string[12:16]}-{hex_string[16:20]}-{hex_string[20:]}"
    
    # Ensure it is a UUIDv4:
    # - Version: set 4th nibble (bits 48-51) to '4'
    # - Variant: set bits 64-65 to '10'
    formatted_uuid = (
        formatted_uuid[:14] + '4' + formatted_uuid[15:]  # Version 4
    )
    formatted_uuid = (
        formatted_uuid[:19] +
        hex((int(formatted_uuid[19], 16) & 0b0011) | 0b1000)[2:] +  # Variant 10
        formatted_uuid[20:]
    )
    
    return formatted_uuid