#!/user/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2021/9/3 23:18
# @Author  : Leslie Wong
# @FileName: mongoutils.py
# @Software: PyCharm

import logging
from pymongo import MongoClient


class MongoUtils:
	"""
	class for masterpiecesShot deployer,
	to deploy the json data to a MongoDB Atlas collection, ready for website implementation
	"""

	def __init__(self):
		self.db = ""

	def create_mongodb_instance(self, url: str, database: str) -> bool:
		try:
			client = MongoClient(url)
			self.db = client[database]
			if self.db:
				return True
			else:
				return False
		except Exception as e:
			logging.error("Method create_mongodb_instance error!")
			logging.exception(e)

	def insert_one_record_to_mongodb(self, collection: str, record: dict) -> bool:
		try:
			print(record)
			result = self.db[collection].insert_one(record)
			if result.inserted_id:
				print(f"Record inserts successfully: {str(result.inserted_id)}")
				return True
			else:
				return False
		except Exception as e:
			logging.error("Method insert_one_record_to_mongodb error!")
			logging.exception(e)

	def insert_many_records_to_mongodb(self, collection: str, records: list) -> bool:
		try:
			print(len(records))
			result = self.db[collection].insert_many(records)
			if result.acknowledged:
				print(f"Records insert successfully {str(result)}")
				return True
			else:
				return False
		except Exception as e:
			logging.error("Method insert_many_records_to_mongodb error!")
			logging.exception(e)

	def update_one_record_of_mongodb(self, collection: str, record_filter: dict, update_info: dict) -> bool:
		try:
			print(record_filter)
			updateDict = {"$set": update_info}
			result = self.db[collection].update_one(record_filter, updateDict)
			if result:
				print(f"Record updates successfully: {str(result)}")
				return True
			else:
				return False
		except Exception as e:
			logging.error("Method update_one_record_of_mongodb error!")
			logging.error(e)

	def get_one_record_from_mongodb(self, collection: str, filter: dict = {}, exclude: list = []) -> list:
		try:
			result = [self.db[collection].find_one(filter)]
			for doc in result:
				for i in exclude:
					del doc[i]
			return result
		except Exception as e:
			logging.error("Method get_one_record_from_mongodb error!")
			logging.error(e)

	def get_many_records_from_mongodb(self, collection: str, filter: dict = {},
									  limit: str = "10000", exclude: list = []) -> list:
		try:
			result = [doc for doc in self.db[collection].find(filter).limit(int(limit))]
			for doc in result:
				for i in exclude:
					del doc[i]
			return result
		except Exception as e:
			logging.error("Method get_many_records_from_mongodb error!")
			logging.error(e)

	def get_collection_count_from_mongodb(self, collection: str, filter: dict = {}) -> int:
		try:
			count = self.db[collection].count_documents(filter)
			return count
		except Exception as e:
			logging.error("Method get_collection_size_from_mongodb error!")
			logging.error(e)

	def get_search_results_from_mongodb(self, collection: str, query: str, index: str, limit: str = "10000", project: dict = {}) -> list:
		try:
			result = self.db[collection].aggregate([
				{
					"$search": {
						"index": index,
						"text": {
							"query": query,
							"path": {"wildcard": "*"}
						}
					}
				}, {
					"$limit": int(limit)
				}, {
					"$project": project
				}
			])
			real_result = []
			for i in result:
				real_result.append(i)
			return real_result
		except Exception as e:
			logging.error("Method get_search_results_from_mongodb error!")
			logging.error(e)
