from mastodon import Mastodon
from mastodon.errors import MastodonAPIError
import requests
import re
import os

mastodon = Mastodon(
	access_token=os.environ.get("MASTODON_SECRET"),
	api_base_url="https://mastodon.social"
	)

url_base = "https://web.navan.dev"
sample_markdown_file = "Content/posts/2022-12-25-blog-to-toot.md"

tags = []
toots = []
image_idx = 0
markdown_image = r'(?:!\[(.*?)\]\((.*?)\))'
markdown_links = r'(?:\[(.*?)\]\((.*?)\))'

def get_image(code, language: str = "python", title: str = "Code Snippet"):
	params = (
	    ('code', code),
	    ('language', language),
	    ('title', title),
	)

	response = requests.get('http://localhost:3000/api', params=params)

	return response.content

class TootContent:
	def __init__(self, text: str = ""):
		self.text = text
		self.images = []
		self.links = []
		self.image_count = len(images)

	def __str__(self):
		toot_text = self.text
		for link in self.links:
			toot_text += " " + link
		return toot_text

	def get_text(self):
		toot_text = self.text
		for link in self.links:
			toot_text += " " + link
		return toot_text

	def get_length(self):
		length = len(self.text)
		for link in self.links:
			length += 23
		return length

	def add_link(self, link):
		if len(self.text) + 23 < 498:
			if link[0].lower() != 'h':
				link = url_base + link
			self.links.append(link)
			return True
		return False

	def add_image(self, image):
		
		if len(self.images) == 4:
			# will handle in future
			print("cannot upload more than 4 images per toot") 
			exit(1)
		# upload image and get id
		self.images.append(image)
		self.image_count = len(self.images)

	def add_text(self, text):
		if len(self.text + text) > 400:
			return False
		else:
			self.text += f" {text}"
			return True

	def get_links(self):
		print(len(self.links))


in_metadata = False
in_code_block = False

my_toots = []
text = ""
images = []
image_links = []
extra_links = []
tags = []

code_block = ""
language = "bash"

current_toot = TootContent()

metadata_regex = r"---\s*\n(.*?)\n---\s*\n"


with open(sample_markdown_file) as f:
	markdown_content = f.read()


metadata = re.search(metadata_regex, markdown_content, re.DOTALL)
if metadata:
	tags_match = re.search(r"tags: ([\w,\s]+)", metadata.group(1))
	if tags_match:
		tags = tags_match.group(1).split(",")


markdown_content = markdown_content.rsplit("---\n",1)[-1].strip()

for line in markdown_content.split("\n"):
	if current_toot.get_length() < 400:
		if line.strip() == '':
			continue
		if line[0] == '#':
			line = line.replace("#","".strip())
			if len(my_toots) == 0:
				current_toot.add_text(
					f"{line}: a cross-posted blog post \n"
					)
				hashtags = ""
				for tag in tags:
					hashtags += f"#{tag.strip()},"
				current_toot.add_text(hashtags[:-1])
				my_toots.append(current_toot)
				current_toot = TootContent()
			else:
				my_toots.append(current_toot)
				current_toot = TootContent(text=f"{line}:")
			continue
		else:
			if "```" in line:
				in_code_block = not in_code_block
				if in_code_block:
					language = line.strip().replace("```",'')
					continue
				else:
					with open(f"code-snipped_{image_idx}.png","wb") as f:
						f.write(get_image(code_block, language))
					current_toot.add_image(f"code-snipped_{image_idx}.png")
					image_idx += 1
					code_block = ""
				continue
			if in_code_block:
				line = line.replace("	","\t")
				code_block += line + "\n"
				continue
			if len(re.findall(markdown_image,line)) > 0:
				for image_link in re.findall(markdown_links, line):
					image_link.append(image_link[1])
					# not handled yet
				line = re.sub(markdown_image,"",line)
			if len(re.findall(markdown_links,line)) > 0:
				for link in re.findall(markdown_links, line):
					if not (current_toot.add_link(link[1])):
						extra_links.append(link[1])
					line = line.replace(f'[{link[0]}]({link[1]})',link[0])
			if not current_toot.add_text(line):
				my_toots.append(current_toot)
				current_toot = TootContent(line)
	else:
		my_toots.append(current_toot)
		current_toot = TootContent()

my_toots.append(current_toot)

in_reply_to_id = None
for toot in my_toots:
	image_ids = []
	for image in toot.images:
		print(f"uploading image, {image}")
		try:
			image_id = mastodon.media_post(image)
			image_ids.append(image_id.id)
		except MastodonAPIError:
			print("failed to upload. Continuing...")
	if image_ids == []:
		image_ids = None
		
	in_reply_to_id = mastodon.status_post(
		toot.get_text(), in_reply_to_id=in_reply_to_id, media_ids=image_ids
		).id