# Copyright (c) 2015, JINGROW and Contributors
# License: MIT. See LICENSE

import os
import shutil
from pathlib import Path

import jingrow
import jingrow.model
from jingrow.modules import get_module_path, scrub, scrub_dt_dn


def export_pg(pg):
	write_document_file(pg)


def export_to_files(record_list=None, record_module=None, verbose=0, create_init=None):
	"""
	Export record_list to files. record_list is a list of lists ([pagetype, pagename, folder name],)  ,
	"""
	if jingrow.flags.in_import:
		return

	if record_list:
		for record in record_list:
			folder_name = record[2] if len(record) == 3 else None
			write_document_file(
				jingrow.get_pg(record[0], record[1]),
				record_module,
				create_init=create_init,
				folder_name=folder_name,
			)


def write_document_file(pg, record_module=None, create_init=True, folder_name=None):
	pg_export = pg.as_dict(no_nulls=True)
	pg.run_method("before_export", pg_export)

	pg_export = strip_default_fields(pg, pg_export)
	module = record_module or get_module_name(pg)
	is_custom_module = jingrow.db.get_value("Module Def", module, "custom")

	# create folder
	if folder_name:
		folder = create_folder(module, folder_name, pg.name, create_init, is_custom_module)
	else:
		folder = create_folder(module, pg.pagetype, pg.name, create_init, is_custom_module)

	fname = scrub(pg.name)
	write_code_files(folder, fname, pg, pg_export)

	# write the data file
	path = os.path.join(folder, f"{fname}.json")
	if is_custom_module and not Path(path).resolve().is_relative_to(Path(jingrow.get_site_path()).resolve()):
		jingrow.throw("Invalid export path: " + Path(path).as_posix())
	with open(path, "w+") as txtfile:
		txtfile.write(jingrow.as_json(pg_export))
	print(f"Wrote document file for {pg.pagetype} {pg.name} at {path}")


def strip_default_fields(pg, pg_export):
	# strip out default fields from children
	if pg.pagetype == "PageType" and pg.migration_hash:
		del pg_export["migration_hash"]

	for df in pg.meta.get_table_fields():
		for d in pg_export.get(df.fieldname):
			for fieldname in jingrow.model.default_fields + jingrow.model.child_table_fields:
				if fieldname in d:
					del d[fieldname]

	return pg_export


def write_code_files(folder, fname, pg, pg_export):
	"""Export code files and strip from values"""
	if hasattr(pg, "get_code_fields"):
		for key, extn in pg.get_code_fields().items():
			if pg.get(key):
				path = os.path.join(folder, fname + "." + extn)
				if not Path(path).resolve().is_relative_to(Path(jingrow.get_site_path()).resolve()):
					jingrow.throw("Invalid export path: " + Path(path).as_posix())
				with open(path, "w+") as txtfile:
					txtfile.write(pg.get(key))

				# remove from exporting
				del pg_export[key]


def get_module_name(pg):
	if pg.pagetype == "Module Def":
		module = pg.name
	elif pg.pagetype == "Workflow":
		module = jingrow.db.get_value("PageType", pg.document_type, "module")
	elif hasattr(pg, "module"):
		module = pg.module
	else:
		module = jingrow.db.get_value("PageType", pg.pagetype, "module")

	return module


def delete_folder(module, dt, dn):
	if jingrow.db.get_value("Module Def", module, "custom"):
		module_path = get_custom_module_path(module)
	else:
		module_path = get_module_path(module)

	dt, dn = scrub_dt_dn(dt, dn)

	# delete folder
	folder = os.path.join(module_path, dt, dn)

	if os.path.exists(folder):
		shutil.rmtree(folder)


def create_folder(module, dt, dn, create_init, is_custom_module):
	if is_custom_module:
		module_path = get_custom_module_path(module)
	else:
		module_path = get_module_path(module)

	dt, dn = scrub_dt_dn(dt, dn)

	# create folder
	folder = os.path.join(module_path, dt, dn)

	jingrow.create_folder(folder)

	# create init_py_files
	if create_init:
		create_init_py(module_path, dt, dn)

	return folder


def get_custom_module_path(module):
	package = jingrow.db.get_value("Module Def", module, "package")
	if not package:
		jingrow.throw(f"Package must be set for custom Module <b>{module}</b>")

	path = os.path.join(get_package_path(package), scrub(module))
	if not Path(path).resolve().is_relative_to(Path(jingrow.get_site_path()).resolve()):
		jingrow.throw("Invalid module path: " + Path(path).as_posix())

	if not os.path.exists(path):
		os.makedirs(path)

	return path


def get_package_path(package):
	path = os.path.join(
		jingrow.get_site_path("packages"), jingrow.db.get_value("Package", package, "package_name")
	)
	if not os.path.exists(path):
		os.makedirs(path)
	return path


def create_init_py(module_path, dt, dn):
	def create_if_not_exists(path):
		initpy = os.path.join(path, "__init__.py")
		if not os.path.exists(initpy):
			open(initpy, "w").close()

	create_if_not_exists(os.path.join(module_path))
	create_if_not_exists(os.path.join(module_path, dt))
	create_if_not_exists(os.path.join(module_path, dt, dn))
