# Copyright (c) 2023, XhiveFramework Technologies and Contributors
# See LICENSE

import time

import xhiveframework
from xhiveframework.core.doctype.doctype.test_doctype import new_doctype
from xhiveframework.desk.doctype.bulk_update.bulk_update import submit_cancel_or_update_docs
from xhiveframework.tests.utils import XhiveFrameworkTestCase, timeout


class TestBulkUpdate(XhiveFrameworkTestCase):
	@classmethod
	def setUpClass(cls) -> None:
		super().setUpClass()
		cls.doctype = new_doctype(is_submittable=1, custom=1).insert().name
		xhiveframework.db.commit()
		for _ in range(50):
			xhiveframework.new_doc(cls.doctype, some_fieldname=xhiveframework.mock("name")).insert()

	@timeout()
	def wait_for_assertion(self, assertion):
		"""Wait till an assertion becomes True"""
		while True:
			if assertion():
				break
			time.sleep(0.2)

	def test_bulk_submit_in_background(self):
		unsubmitted = xhiveframework.get_all(self.doctype, {"docstatus": 0}, limit=5, pluck="name")
		failed = submit_cancel_or_update_docs(self.doctype, unsubmitted, action="submit")
		self.assertEqual(failed, [])

		def check_docstatus(docs, status):
			xhiveframework.db.rollback()
			matching_docs = xhiveframework.get_all(
				self.doctype, {"docstatus": status, "name": ("in", docs)}, pluck="name"
			)
			return set(matching_docs) == set(docs)

		unsubmitted = xhiveframework.get_all(self.doctype, {"docstatus": 0}, limit=20, pluck="name")
		submit_cancel_or_update_docs(self.doctype, unsubmitted, action="submit")

		self.wait_for_assertion(lambda: check_docstatus(unsubmitted, 1))

		submitted = xhiveframework.get_all(self.doctype, {"docstatus": 1}, limit=20, pluck="name")
		submit_cancel_or_update_docs(self.doctype, submitted, action="cancel")
		self.wait_for_assertion(lambda: check_docstatus(submitted, 2))
