# Copyright (c) 2019, InfluxFramework LLC
# License: MIT. See LICENSE

import sqlparse

import influxframework
import influxframework.recorder
from influxframework.tests.utils import InfluxFrameworkTestCase
from influxframework.utils import set_request
from influxframework.website.serve import get_response_content


class TestRecorder(InfluxFrameworkTestCase):
	def setUp(self):
		influxframework.recorder.stop()
		influxframework.recorder.delete()
		set_request()
		influxframework.recorder.start()
		influxframework.recorder.record()

	def test_start(self):
		influxframework.recorder.dump()
		requests = influxframework.recorder.get()
		self.assertEqual(len(requests), 1)

	def test_do_not_record(self):
		influxframework.recorder.do_not_record(influxframework.get_all)("DocType")
		influxframework.recorder.dump()
		requests = influxframework.recorder.get()
		self.assertEqual(len(requests), 0)

	def test_get(self):
		influxframework.recorder.dump()

		requests = influxframework.recorder.get()
		self.assertEqual(len(requests), 1)

		request = influxframework.recorder.get(requests[0]["uuid"])
		self.assertTrue(request)

	def test_delete(self):
		influxframework.recorder.dump()

		requests = influxframework.recorder.get()
		self.assertEqual(len(requests), 1)

		influxframework.recorder.delete()

		requests = influxframework.recorder.get()
		self.assertEqual(len(requests), 0)

	def test_record_without_sql_queries(self):
		influxframework.recorder.dump()

		requests = influxframework.recorder.get()
		request = influxframework.recorder.get(requests[0]["uuid"])

		self.assertEqual(len(request["calls"]), 0)

	def test_record_with_sql_queries(self):
		influxframework.get_all("DocType")
		influxframework.recorder.dump()

		requests = influxframework.recorder.get()
		request = influxframework.recorder.get(requests[0]["uuid"])

		self.assertNotEqual(len(request["calls"]), 0)

	def test_explain(self):
		influxframework.db.sql("SELECT * FROM tabDocType")
		influxframework.db.sql("COMMIT")
		influxframework.recorder.dump()

		requests = influxframework.recorder.get()
		request = influxframework.recorder.get(requests[0]["uuid"])

		self.assertEqual(len(request["calls"][0]["explain_result"]), 1)
		self.assertEqual(len(request["calls"][1]["explain_result"]), 0)

	def test_multiple_queries(self):
		queries = [
			{"mariadb": "SELECT * FROM tabDocType", "postgres": 'SELECT * FROM "tabDocType"'},
			{"mariadb": "SELECT COUNT(*) FROM tabDocType", "postgres": 'SELECT COUNT(*) FROM "tabDocType"'},
			{"mariadb": "COMMIT", "postgres": "COMMIT"},
		]

		sql_dialect = influxframework.db.db_type or "mariadb"
		for query in queries:
			influxframework.db.sql(query[sql_dialect])

		influxframework.recorder.dump()

		requests = influxframework.recorder.get()
		request = influxframework.recorder.get(requests[0]["uuid"])

		self.assertEqual(len(request["calls"]), len(queries))

		for query, call in zip(queries, request["calls"]):
			self.assertEqual(
				call["query"], sqlparse.format(query[sql_dialect].strip(), keyword_case="upper", reindent=True)
			)

	def test_duplicate_queries(self):
		queries = [
			("SELECT * FROM tabDocType", 2),
			("SELECT COUNT(*) FROM tabDocType", 1),
			("select * from tabDocType", 2),
			("COMMIT", 3),
			("COMMIT", 3),
			("COMMIT", 3),
		]
		for query in queries:
			influxframework.db.sql(query[0])

		influxframework.recorder.dump()

		requests = influxframework.recorder.get()
		request = influxframework.recorder.get(requests[0]["uuid"])

		for query, call in zip(queries, request["calls"]):
			self.assertEqual(call["exact_copies"], query[1])

	def test_error_page_rendering(self):
		content = get_response_content("error")
		self.assertIn("Error", content)
