# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt

import copy
import signal
import unittest
from contextlib import contextmanager
from typing import Any, Dict, NewType, Optional

import frappe
from frappe.core.doctype.report.report import get_report_module_dotted_path

ReportFilters = Dict[str, Any]
ReportName = NewType("ReportName", str)


class ERPNextTestCase(unittest.TestCase):
	"""A sane default test class for ERPNext tests."""


	@classmethod
	def setUpClass(cls) -> None:
		frappe.db.commit()
		return super().setUpClass()

	@classmethod
	def tearDownClass(cls) -> None:
		frappe.db.rollback()
		return super().tearDownClass()


def create_test_contact_and_address():
	frappe.db.sql('delete from tabContact')
	frappe.db.sql('delete from `tabContact Email`')
	frappe.db.sql('delete from `tabContact Phone`')
	frappe.db.sql('delete from tabAddress')
	frappe.db.sql('delete from `tabDynamic Link`')

	frappe.get_doc({
		"doctype": "Address",
		"address_title": "_Test Address for Customer",
		"address_type": "Office",
		"address_line1": "Station Road",
		"city": "_Test City",
		"state": "Test State",
		"country": "India",
		"links": [
			{
				"link_doctype": "Customer",
				"link_name": "_Test Customer"
			}
		]
	}).insert()

	contact = frappe.get_doc({
		"doctype": 'Contact',
		"first_name": "_Test Contact for _Test Customer",
		"links": [
			{
				"link_doctype": "Customer",
				"link_name": "_Test Customer"
			}
		]
	})
	contact.add_email("test_contact_customer@example.com", is_primary=True)
	contact.add_phone("+91 0000000000", is_primary_phone=True)
	contact.insert()


@contextmanager
def change_settings(doctype, settings_dict):
	""" A context manager to ensure that settings are changed before running
	function and restored after running it regardless of exceptions occured.
	This is useful in tests where you want to make changes in a function but
	don't retain those changes.
	import and use as decorator to cover full function or using `with` statement.

	example:
	@change_settings("Stock Settings", {"item_naming_by": "Naming Series"})
	def test_case(self):
		...
	"""

	try:
		settings = frappe.get_doc(doctype)
		# remember setting
		previous_settings = copy.deepcopy(settings_dict)
		for key in previous_settings:
			previous_settings[key] = getattr(settings, key)

		# change setting
		for key, value in settings_dict.items():
			setattr(settings, key, value)
		settings.save()
		yield # yield control to calling function

	finally:
		# restore settings
		settings = frappe.get_doc(doctype)
		for key, value in previous_settings.items():
			setattr(settings, key, value)
		settings.save()


def execute_script_report(
		report_name: ReportName,
		module: str,
		filters: ReportFilters,
		default_filters: Optional[ReportFilters] = None,
		optional_filters: Optional[ReportFilters] = None
	):
	"""Util for testing execution of a report with specified filters.

	Tests the execution of report with default_filters + filters.
	Tests the execution using optional_filters one at a time.

	Args:
		report_name: Human readable name of report (unscrubbed)
		module: module to which report belongs to
		filters: specific values for filters
		default_filters: default values for filters such as company name.
		optional_filters: filters which should be tested one at a time in addition to default filters.
	"""

	if default_filters is None:
		default_filters = {}

	report_execute_fn = frappe.get_attr(get_report_module_dotted_path(module, report_name) + ".execute")
	report_filters = frappe._dict(default_filters).copy().update(filters)

	report_data = report_execute_fn(report_filters)

	if optional_filters:
		for key, value in optional_filters.items():
			filter_with_optional_param = report_filters.copy().update({key: value})
			report_execute_fn(filter_with_optional_param)

	return report_data


def timeout(seconds=30, error_message="Test timed out."):
	""" Timeout decorator to ensure a test doesn't run for too long.

		adapted from https://stackoverflow.com/a/2282656"""
	def decorator(func):
		def _handle_timeout(signum, frame):
			raise Exception(error_message)

		def wrapper(*args, **kwargs):
			signal.signal(signal.SIGALRM, _handle_timeout)
			signal.alarm(seconds)
			try:
				result = func(*args, **kwargs)
			finally:
				signal.alarm(0)
			return result
		return wrapper
	return decorator
