# Copyright (c) 2023, JINGROW and Contributors
# See license.txt

import jingrow
from jingrow.tests.utils import JingrowTestCase


class TestAuditTrail(JingrowTestCase):
	def setUp(self):
		self.child_pagetype = create_custom_child_pagetype()
		self.custom_pagetype = create_custom_pagetype()

	def test_compare_changed_fields(self):
		pg = jingrow.new_pg("Test Custom Pagetype for Pg Comparator")
		pg.test_field = "first value"
		pg.submit()
		pg.cancel()

		changed_fields = jingrow._dict(test_field="second value")
		amended_pg = amend_document(pg, changed_fields, {}, 1)
		amended_pg.cancel()

		changed_fields = jingrow._dict(test_field="third value")
		re_amended_pg = amend_document(amended_pg, changed_fields, {}, 1)

		comparator = create_comparator_pg("Test Custom Pagetype for Pg Comparator", re_amended_pg.name)
		documents, results = comparator.compare_document()

		test_field_values = results["changed"]["Field"]
		self.check_expected_values(test_field_values, ["first value", "second value", "third value"])

	def test_compare_rows(self):
		pg = jingrow.new_pg("Test Custom Pagetype for Pg Comparator")
		pg.append("child_table_field", {"test_table_field": "old row 1 value"})
		pg.submit()
		pg.cancel()

		child_table_new = [{"test_table_field": "new row 1 value"}, {"test_table_field": "row 2 value"}]
		rows_updated = jingrow._dict(child_table_field=child_table_new)
		amended_pg = amend_document(pg, {}, rows_updated, 1)

		comparator = create_comparator_pg("Test Custom Pagetype for Pg Comparator", amended_pg.name)
		documents, results = comparator.compare_document()

		results = jingrow._dict(results)
		self.check_rows_updated(results.row_changed)
		self.check_rows_added(results.added[amended_pg.name])

	def check_rows_updated(self, row_changed):
		self.assertIn("Child Table Field", row_changed)
		self.assertIn(0, row_changed["Child Table Field"])
		self.assertIn("Table Field", row_changed["Child Table Field"][0])
		table_field_values = row_changed["Child Table Field"][0]["Table Field"]
		self.check_expected_values(table_field_values, ["old row 1 value", "new row 1 value"])

	def check_rows_added(self, rows_added):
		self.assertIn("Child Table Field", rows_added)
		child_table = rows_added["Child Table Field"]
		self.assertIn("Table Field", child_table[0])
		self.check_expected_values(child_table[0]["Table Field"], "row 2 value")

	def check_expected_values(self, values_to_check, expected_values):
		for i in range(len(values_to_check)):
			self.assertEqual(values_to_check[i], expected_values[i])

	def tearDown(self):
		self.child_pagetype.delete()
		self.custom_pagetype.delete()


def create_custom_child_pagetype():
	child_pagetype = jingrow.get_pg(
		{
			"pagetype": "PageType",
			"module": "Core",
			"name": "Test Custom Child for Pg Comparator",
			"custom": 1,
			"istable": 1,
			"fields": [
				{
					"label": "Table Field",
					"fieldname": "test_table_field",
					"fieldtype": "Data",
					"in_list_view": 1,
				},
			],
		}
	).insert(ignore_if_duplicate=True)
	return child_pagetype


def create_custom_pagetype():
	custom_pagetype = jingrow.get_pg(
		{
			"pagetype": "PageType",
			"module": "Core",
			"name": "Test Custom Pagetype for Pg Comparator",
			"custom": 1,
			"is_submittable": 1,
			"fields": [
				{
					"label": "Field",
					"fieldname": "test_field",
					"fieldtype": "Data",
				},
				{
					"label": "Child Table Field",
					"fieldname": "child_table_field",
					"fieldtype": "Table",
					"options": "Test Custom Child for Pg Comparator",
				},
			],
			"permissions": [{"role": "System Manager", "read": 1}],
		}
	).insert(ignore_if_duplicate=True)
	return custom_pagetype


def amend_document(amend_from, changed_fields, rows_updated, submit=False):
	amended_pg = jingrow.copy_pg(amend_from)
	amended_pg.amended_from = amend_from.name
	amended_pg.update(changed_fields)
	for child_table in rows_updated:
		amended_pg.set(child_table, rows_updated[child_table])
	if submit:
		amended_pg.submit()
	return amended_pg


def create_comparator_pg(pagetype_name, document):
	comparator = jingrow.new_pg("Audit Trail")
	comparator.pagetype_name = pagetype_name
	comparator.document = document
	return comparator
