import jingrow
from jingrow.desk.form.linked_with import get_linked_pagetypes
from jingrow.patches.v11_0.replicate_old_user_permissions import get_pagetypes_to_skip
from jingrow.query_builder import Field

# `skip_for_pagetype` was a un-normalized way of storing for which
# pagetypes the user permission was applicable.
# in this patch, we normalize this into `applicable_for` where
# a new record will be created for each pagetype where the user permission
# is applicable
#
# if the user permission is applicable for all pagetypes, then only
# one record is created


def execute():
	jingrow.reload_pagetype("User Permission")

	# to check if we need to migrate from skip_for_pagetype
	has_skip_for_pagetype = jingrow.db.has_column("User Permission", "skip_for_pagetype")
	skip_for_pagetype_map = {}

	new_user_permissions_list = []

	user_permissions_to_delete = []

	for user_permission in jingrow.get_all("User Permission", fields=["*"]):
		skip_for_pagetype = []

		# while migrating from v11 -> v11
		if has_skip_for_pagetype:
			if not user_permission.skip_for_pagetype:
				continue
			skip_for_pagetype = user_permission.skip_for_pagetype.split("\n")
		else:  # while migrating from v10 -> v11
			if skip_for_pagetype_map.get((user_permission.allow, user_permission.user)) is None:
				skip_for_pagetype = get_pagetypes_to_skip(user_permission.allow, user_permission.user)
				# cache skip for pagetype for same user and pagetype
				skip_for_pagetype_map[(user_permission.allow, user_permission.user)] = skip_for_pagetype
			else:
				skip_for_pagetype = skip_for_pagetype_map[(user_permission.allow, user_permission.user)]

		if skip_for_pagetype:
			# only specific pagetypes are selected
			# split this into multiple records and delete
			linked_pagetypes = get_linked_pagetypes(user_permission.allow, True).keys()

			linked_pagetypes = list(linked_pagetypes)

			# append the pagetype for which we have build the user permission
			linked_pagetypes += [user_permission.allow]

			applicable_for_pagetypes = list(set(linked_pagetypes) - set(skip_for_pagetype))

			user_permissions_to_delete.append(user_permission.name)
			user_permission.name = None
			user_permission.skip_for_pagetype = None
			new_user_permissions_list.extend(
				(
					jingrow.generate_hash(length=10),
					user_permission.user,
					user_permission.allow,
					user_permission.for_value,
					pagetype,
					0,
					user_permission.creation,
					user_permission.modified,
				)
				for pagetype in applicable_for_pagetypes
				if pagetype
			)
		else:
			# No skip_for_pagetype found! Just update apply_to_all_pagetypes.
			jingrow.db.set_value("User Permission", user_permission.name, "apply_to_all_pagetypes", 1)

	if new_user_permissions_list:
		jingrow.qb.into("User Permission").columns(
			"name",
			"user",
			"allow",
			"for_value",
			"applicable_for",
			"apply_to_all_pagetypes",
			"creation",
			"modified",
		).insert(*new_user_permissions_list).run()

	if user_permissions_to_delete:
		jingrow.db.delete("User Permission", filters=(Field("name").isin(tuple(user_permissions_to_delete))))
