
from bs4 import BeautifulSoup
import functools
import json
import random
import re
import string

def formkey_from(text):
    soup = BeautifulSoup(text, 'html.parser')
    formkey = next(tag for tag in soup.find_all("input") if tag.get("name") == "formkey").get("value")
    return formkey

# not cryptographically secure, deal with it
def generate_text():
    return ''.join(random.choices(string.ascii_lowercase, k=40))

# Annotation to put around tests that don't care about rate limits
def no_rate_limit(test_function):
	@functools.wraps(test_function)
	def wrapped(*args, **kwargs):
		from files.__main__ import app, limiter
		was_enabled = limiter.enabled
		app.config['RATE_LIMITER_ENABLED'] = False
		limiter.enabled = False
		try:
			result = test_function(*args, **kwargs)
			app.config['RATE_LIMITER_ENABLED'] = was_enabled
			limiter.enabled = was_enabled
			return result
		except Exception as e:
			app.config['RATE_LIMITER_ENABLED'] = was_enabled
			limiter.enabled = was_enabled
			raise e
	return wrapped

# this is meant to be a utility class that stores post and comment references so you can use them in other calls
# it's pretty barebones and will probably be fleshed out
class ItemData:
    id: str | None = None
    id_full: str | None = None
    url: str | None = None

    @staticmethod
    def from_html(text):
        soup = BeautifulSoup(text, 'html.parser')
        url = soup.find("meta", property="og:url")["content"]

        match = re.search(r'/post/(\d+)/', url)
        if match is None:
            return None
        
        result = ItemData()
        result.id = match.group(1)  	# this really should get yanked out of the JS, not the URL
        result.id_full = f"post_{result.id}"
        result.url = url
        return result

    @staticmethod
    def from_json(text):
        data = json.loads(text)

        soup = BeautifulSoup(data["comment"], 'html.parser')
        divid = soup.find("div")["id"]

        match = re.search(r'comment-(\d+)', divid)
        if match is None:
            return None
        
        result = ItemData()
        result.id = match.group(1)  	# this really should get yanked out of the JS, not the HTML
        result.id_full = f"comment_{result.id}"
        result.url = f"/comment/{result.id}"
        return result
