# Copyright (c) 2015, JINGROW and Contributors
# License: MIT. See LICENSE
import jingrow
from jingrow.core.page.permission_manager.permission_manager import add, reset, update
from jingrow.custom.pagetype.property_setter.property_setter import make_property_setter
from jingrow.desk.form.load import get_pageinfo, getpage, getpagetype
from jingrow.tests.utils import JingrowTestCase
from jingrow.utils.file_manager import save_file

test_dependencies = ["Blog Category", "Blogger"]


class TestFormLoad(JingrowTestCase):
	def test_load(self):
		getpagetype("PageType")
		meta = next(filter(lambda d: d.name == "PageType", jingrow.response.pgs))
		self.assertEqual(meta.name, "PageType")
		self.assertTrue(meta.get("__js"))

		jingrow.response.pgs = []
		getpagetype("Event")
		meta = next(filter(lambda d: d.name == "Event", jingrow.response.pgs))
		self.assertTrue(meta.get("__calendar_js"))

	def test_fieldlevel_permissions_in_load(self):
		blog = jingrow.get_pg(
			{
				"pagetype": "Blog Post",
				"blog_category": "-test-blog-category-1",
				"blog_intro": "Test Blog Intro",
				"blogger": "_Test Blogger 1",
				"content": "Test Blog Content",
				"title": f"_Test Blog Post {jingrow.utils.now()}",
				"published": 0,
			}
		)

		blog.insert()

		user = jingrow.get_pg("User", "test@example.com")

		user_roles = jingrow.get_roles()
		user.remove_roles(*user_roles)
		user.add_roles("Blogger")

		blog_post_property_setter = make_property_setter("Blog Post", "published", "permlevel", 1, "Int")
		reset("Blog Post")

		# test field level permission before role level permissions are defined
		jingrow.set_user(user.name)
		blog_pg = get_blog(blog.name)

		with self.assertRaises(AttributeError):
			blog_pg.published

		# this will be ignored because user does not
		# have write access on `published` field (or on permlevel 1 fields)
		blog_pg.published = 1
		blog_pg.save()

		# since published field has higher permlevel
		self.assertEqual(blog_pg.published, 0)

		# test field level permission after role level permissions are defined
		jingrow.set_user("Administrator")
		add("Blog Post", "Website Manager", 1)
		update("Blog Post", "Website Manager", 1, "write", 1)

		jingrow.set_user(user.name)
		blog_pg = get_blog(blog.name)

		self.assertEqual(blog_pg.name, blog.name)
		# since published field has higher permlevel
		with self.assertRaises(AttributeError):
			blog_pg.published

		# this will be ignored because user does not
		# have write access on `published` field (or on permlevel 1 fields)
		blog_pg.published = 1
		blog_pg.save()

		# since published field has higher permlevel
		self.assertEqual(blog_pg.published, 0)

		jingrow.set_user("Administrator")
		user.add_roles("Website Manager")
		jingrow.set_user(user.name)

		pg = jingrow.get_pg("Blog Post", blog.name)
		pg.published = 1
		pg.save()

		blog_pg = get_blog(blog.name)
		# now user should be allowed to read field with higher permlevel
		# (after adding Website Manager role)
		self.assertEqual(blog_pg.published, 1)

		jingrow.set_user("Administrator")

		# reset user roles
		user.remove_roles("Blogger", "Website Manager")
		user.add_roles(*user_roles)

		blog_pg.delete()
		jingrow.delete_pg(blog_post_property_setter.pagetype, blog_post_property_setter.name)

	def test_fieldlevel_permissions_in_load_for_child_table(self):
		contact = jingrow.new_pg("Contact")
		contact.first_name = "_Test Contact 1"
		contact.append("phone_nos", {"phone": "123456"})
		contact.insert()

		user = jingrow.get_pg("User", "test@example.com")

		user_roles = jingrow.get_roles()
		user.remove_roles(*user_roles)
		user.add_roles("Accounts User")

		make_property_setter("Contact Phone", "phone", "permlevel", 1, "Int")
		reset("Contact Phone")
		add("Contact", "Sales User", 1)
		update("Contact", "Sales User", 1, "write", 1)

		jingrow.set_user(user.name)

		contact = jingrow.get_pg("Contact", "_Test Contact 1")

		contact.phone_nos[0].phone = "654321"
		contact.save()

		self.assertEqual(contact.phone_nos[0].phone, "123456")

		jingrow.set_user("Administrator")
		user.add_roles("Sales User")
		jingrow.set_user(user.name)

		contact.phone_nos[0].phone = "654321"
		contact.save()

		contact = jingrow.get_pg("Contact", "_Test Contact 1")
		self.assertEqual(contact.phone_nos[0].phone, "654321")

		jingrow.set_user("Administrator")

		# reset user roles
		user.remove_roles("Accounts User", "Sales User")
		user.add_roles(*user_roles)

		contact.delete()

	def test_get_pg_info(self):
		note = jingrow.new_pg("Note")
		note.content = "some content"
		note.title = jingrow.generate_hash(length=20)
		note.insert()

		note.content = "new content"
		# trigger a version
		note.save(ignore_version=False)

		note.add_comment(text="test")

		note.add_tag("test_tag")
		note.add_tag("more_tag")

		# empty attachment
		save_file("test_file", b"", note.pagetype, note.name, decode=True)

		jingrow.get_pg(
			{
				"pagetype": "Email",
				"content": "test email",
				"reference_pagetype": note.pagetype,
				"reference_name": note.name,
			}
		).insert()

		get_pageinfo(note)
		pageinfo = jingrow.response["pageinfo"]

		self.assertEqual(len(pageinfo.comments), 1)
		self.assertIn("test", pageinfo.comments[0].content)

		self.assertGreaterEqual(len(pageinfo.versions), 1)

		self.assertEqual(set(pageinfo.tags.split(",")), {"more_tag", "test_tag"})

		self.assertEqual(len(pageinfo.attachments), 1)
		self.assertIn("test_file", pageinfo.attachments[0].file_name)

		self.assertEqual(len(pageinfo.communications), 1)
		self.assertIn("email", pageinfo.communications[0].content)
		note.delete()


def get_blog(blog_name):
	jingrow.response.pgs = []
	getpage("Blog Post", blog_name)
	return jingrow.response.pgs[0]
