# Copyright (c) 2021, JINGROW
# For license information, please see license.txt

import json
import os
import subprocess

import jingrow
from jingrow.desk.form.load import get_attachments
from jingrow.model.page import Page
from jingrow.model.sync import get_pg_files
from jingrow.modules.import_file import import_pg, import_file_by_path
from jingrow.utils import get_files_path


class PackageImport(Page):
	# begin: auto-generated types
	# This code is auto-generated. Do not modify anything in this block.

	from typing import TYPE_CHECKING

	if TYPE_CHECKING:
		from jingrow.types import DF

		activate: DF.Check
		attach_package: DF.Attach | None
		force: DF.Check
		log: DF.Code | None

	# end: auto-generated types
	def validate(self):
		if self.activate:
			self.import_package()

	def validate_custom_fields(self, files):
		non_custom_pagetypes = []
		
		for file_path in files:
			try:
				with open(file_path, 'r', encoding='utf-8') as f:
					pg_data = json.load(f)
				
				if pg_data.get("pagetype") == "PageType":
					pagetype_name = pg_data.get("name")
					custom_value = pg_data.get("custom")
					
					if custom_value != 1:
						non_custom_pagetypes.append(pagetype_name)
						
			except (json.JSONDecodeError, IOError) as e:
				continue
		
		if non_custom_pagetypes:
			pagetype_list = ", ".join(non_custom_pagetypes)
			jingrow.throw(
				jingrow._("The following PageTypes are not custom PageType and cannot be imported:") + "<br>" + pagetype_list
			)

	def import_package(self):
		attachment = get_attachments(self.pagetype, self.name)

		if not attachment:
			jingrow.throw(jingrow._("Please attach the package"))

		attachment = attachment[0]

		# get package_name from file (package_name-0.0.0.tar.gz)
		package_name = attachment.file_name.split(".", 1)[0].rsplit("-", 1)[0]
		if not os.path.exists(jingrow.get_site_path("packages")):
			os.makedirs(jingrow.get_site_path("packages"))

		# extract
		# Use file_url to resolve full path (supports bucket subdirectory paths)
		file_url = attachment.file_url or ""
		stripped = file_url.strip("/")
		if stripped.startswith("private/files/"):
			full_path = get_files_path(*stripped.split("private/files/", 1)[1].split("/"), is_private=1)
		elif stripped.startswith("files/"):
			full_path = get_files_path(*stripped.split("files/", 1)[1].split("/"))
		else:
			full_path = get_files_path(attachment.file_name, is_private=attachment.is_private)

		subprocess.check_output(
			[
				"tar",
				"xzf",
				full_path,
				"-C",
				jingrow.get_site_path("packages"),
			]
		)

		package_path = jingrow.get_site_path("packages", package_name)

		# collect modules
		files = []
		for module in os.listdir(package_path):
			module_path = os.path.join(package_path, module)
			if os.path.isdir(module_path):
				files = get_pg_files(files, module_path)

		self.validate_custom_fields(files)

		# import Package
		with open(os.path.join(package_path, package_name + ".json")) as packagefile:
			pg_dict = json.loads(packagefile.read())

		jingrow.flags.package = import_pg(pg_dict)

		# import files
		log = []
		for file in files:
			import_file_by_path(file, force=self.force, ignore_version=True)
			log.append(f"Imported {file}")

		self.log = "\n".join(log)
