


import json
import os
import shutil
import sys
import tempfile
import unittest
from unittest import TestCase
from unittest.mock import patch

import faiss
import numpy as np
from datasets import Dataset

from transformers import BartConfig, BartTokenizer, DPRConfig, DPRQuestionEncoderTokenizer, RagConfig
from transformers.file_utils import is_datasets_available, is_faiss_available, is_psutil_available, is_torch_available
from transformers.integrations import is_ray_available
from transformers.models.bert.tokenization_bert import VOCAB_FILES_NAMES as DPR_VOCAB_FILES_NAMES
from transformers.models.rag.retrieval_rag import CustomHFIndex, RagRetriever
from transformers.models.roberta.tokenization_roberta import VOCAB_FILES_NAMES as BART_VOCAB_FILES_NAMES
from transformers.testing_utils import require_ray


sys.path.append(os.path.join(os.getcwd()))  # noqa: E402 # noqa: E402 # isort:skip

if is_torch_available():
		from distributed_pytorch_retriever import RagPyTorchDistributedRetriever  # noqa: E402 # isort:skip
else:
		lowerCamelCase		=						None

if is_ray_available():
		import ray  # noqa: E402 # isort:skip
		from distributed_ray_retriever import RagRayDistributedRetriever, RayRetriever  # noqa: E402 # isort:skip
else:
		lowerCamelCase		=						None
		lowerCamelCase		=						None
		lowerCamelCase		=						None






def 	lowerCamelCase_       (			_a			):




		"""simple docstring"""






		if not (is_datasets_available() and is_faiss_available() and is_psutil_available()):
				lowerCAmelCase__  :     Dict       	=   unittest.skip('''test requires Datasets, Faiss, psutil'''			)(_a			)
		return test_case





@require_distributed_retrieval
class    _a				(							_lowercase):




	def 				UpperCAmelCase__(   self		:						List[Any]						)->			List[str]:
			lowerCAmelCase__  :     Any       	=   tempfile.mkdtemp()
			lowerCAmelCase__  :     Dict       	=   8

			# DPR tok
			lowerCAmelCase__  :     str       	=   [
			    '''[UNK]''',
			    '''[CLS]''',
			    '''[SEP]''',
			    '''[PAD]''',
			    '''[MASK]''',
			    '''want''',
			    '''##want''',
			    '''##ed''',
			    '''wa''',
			    '''un''',
			    '''runn''',
			    '''##ing''',
			    ''',''',
			    '''low''',
			    '''lowest''',
			]
			lowerCAmelCase__  :     str       	=   os.path.join(self.tmpdirname						,   '''dpr_tokenizer'''						)
			os.makedirs(_SCREAMING_SNAKE_CASE						,   exist_ok=_SCREAMING_SNAKE_CASE						)
			lowerCAmelCase__  :     Union[str, Any]       	=   os.path.join(_SCREAMING_SNAKE_CASE						,   DPR_VOCAB_FILES_NAMES['''vocab_file''']						)
			with open(self.vocab_file						,   '''w'''						,   encoding='''utf-8'''						) as vocab_writer:
					vocab_writer.write(''''''.join([x + '''\n''' for x in vocab_tokens]						)						)

			# BART tok
			lowerCAmelCase__  :     Tuple       	=   [
			    '''l''',
			    '''o''',
			    '''w''',
			    '''e''',
			    '''r''',
			    '''s''',
			    '''t''',
			    '''i''',
			    '''d''',
			    '''n''',
			    '''\u0120''',
			    '''\u0120l''',
			    '''\u0120n''',
			    '''\u0120lo''',
			    '''\u0120low''',
			    '''er''',
			    '''\u0120lowest''',
			    '''\u0120newer''',
			    '''\u0120wider''',
			    '''<unk>''',
			]
			lowerCAmelCase__  :     Optional[int]       	=   dict(zip(_SCREAMING_SNAKE_CASE						,   range(len(_SCREAMING_SNAKE_CASE						)						)						)						)
			lowerCAmelCase__  :     int       	=   ['''#version: 0.2''', '''\u0120 l''', '''\u0120l o''', '''\u0120lo w''', '''e r''', '''''']
			lowerCAmelCase__  :     Union[str, Any]       	=   {'''unk_token''': '''<unk>'''}

			lowerCAmelCase__  :     int       	=   os.path.join(self.tmpdirname						,   '''bart_tokenizer'''						)
			os.makedirs(_SCREAMING_SNAKE_CASE						,   exist_ok=_SCREAMING_SNAKE_CASE						)
			lowerCAmelCase__  :     List[str]       	=   os.path.join(_SCREAMING_SNAKE_CASE						,   BART_VOCAB_FILES_NAMES['''vocab_file''']						)
			lowerCAmelCase__  :     Tuple       	=   os.path.join(_SCREAMING_SNAKE_CASE						,   BART_VOCAB_FILES_NAMES['''merges_file''']						)
			with open(self.vocab_file						,   '''w'''						,   encoding='''utf-8'''						) as fp:
					fp.write(json.dumps(_SCREAMING_SNAKE_CASE						) + '''\n'''						)
			with open(self.merges_file						,   '''w'''						,   encoding='''utf-8'''						) as fp:
					fp.write('''\n'''.join(_SCREAMING_SNAKE_CASE						)						)




	def 				UpperCAmelCase__(   self		:						str						)->			DPRQuestionEncoderTokenizer:
			return DPRQuestionEncoderTokenizer.from_pretrained(os.path.join(self.tmpdirname						,   '''dpr_tokenizer'''						)						)




	def 				UpperCAmelCase__(   self		:						Optional[int]						)->			BartTokenizer:
			return BartTokenizer.from_pretrained(os.path.join(self.tmpdirname						,   '''bart_tokenizer'''						)						)




	def 				UpperCAmelCase__(   self		:						Tuple						)->			str:
			shutil.rmtree(self.tmpdirname						)




	def 				UpperCAmelCase__(   self		:						Optional[int]						)->			List[Any]:
			lowerCAmelCase__  :     Any       	=   Dataset.from_dict(
			    {
			        '''id''': ['''0''', '''1'''],
			        '''text''': ['''foo''', '''bar'''],
			        '''title''': ['''Foo''', '''Bar'''],
			        '''embeddings''': [np.ones(self.retrieval_vector_size						), 2 * np.ones(self.retrieval_vector_size						)],
			    }						)
			dataset.add_faiss_index('''embeddings'''						,   string_factory='''Flat'''						,   metric_type=faiss.METRIC_INNER_PRODUCT						)
			return dataset




	def 				UpperCAmelCase__(   self		:						List[str]						,   _SCREAMING_SNAKE_CASE		:						bool						,   _SCREAMING_SNAKE_CASE		:						List[str]=1_2345						)->			RagPyTorchDistributedRetriever:
			lowerCAmelCase__  :     Optional[Any]       	=   self.get_dummy_dataset()
			lowerCAmelCase__  :     List[Any]       	=   RagConfig(
			    retrieval_vector_size=self.retrieval_vector_size						,   question_encoder=DPRConfig().to_dict()						,   generator=BartConfig().to_dict()						,   )
			with patch('''transformers.models.rag.retrieval_rag.load_dataset'''						) as mock_load_dataset:
					lowerCAmelCase__  :     Tuple       	=   dataset
					lowerCAmelCase__  :     Dict       	=   RagPyTorchDistributedRetriever(
					    _SCREAMING_SNAKE_CASE						,   question_encoder_tokenizer=self.get_dpr_tokenizer()						,   generator_tokenizer=self.get_bart_tokenizer()						,   )
					if init_retrieval:
							retriever.init_retrieval(_SCREAMING_SNAKE_CASE						)
			return retriever




	def 				UpperCAmelCase__(   self		:						Optional[Any]						,   _SCREAMING_SNAKE_CASE		:						bool						)->			RagRayDistributedRetriever:
			# Have to run in local mode because sys.path modifications at top of
			# file are not propogated to remote workers.
			# https://stackoverflow.com/questions/54338013/parallel-import-a-python-file-from-sibling-folder
			ray.init(local_mode=_SCREAMING_SNAKE_CASE						)
			lowerCAmelCase__  :     List[str]       	=   RagConfig(
			    retrieval_vector_size=self.retrieval_vector_size						,   question_encoder=DPRConfig().to_dict()						,   generator=BartConfig().to_dict()						,   )
			lowerCAmelCase__  :     List[str]       	=   ray.remote(_SCREAMING_SNAKE_CASE						)
			lowerCAmelCase__  :     Any       	=   [remote_cls.remote() for _ in range(1						)]
			with patch('''transformers.models.rag.retrieval_rag.load_dataset'''						) as mock_load_dataset:
					lowerCAmelCase__  :     List[Any]       	=   self.get_dummy_dataset()
					lowerCAmelCase__  :     Union[str, Any]       	=   RagRayDistributedRetriever(
					    _SCREAMING_SNAKE_CASE						,   question_encoder_tokenizer=self.get_dpr_tokenizer()						,   generator_tokenizer=self.get_bart_tokenizer()						,   retrieval_workers=_SCREAMING_SNAKE_CASE						,   )
					if init_retrieval:
							retriever.init_retrieval()
			return retriever




	def 				UpperCAmelCase__(   self		:						Optional[Any]						,   _SCREAMING_SNAKE_CASE		:						bool						,   _SCREAMING_SNAKE_CASE		:						bool						,   _SCREAMING_SNAKE_CASE		:						Union[str, Any]=1_2345						)->			Dict:
			lowerCAmelCase__  :     str       	=   self.get_dummy_dataset()
			lowerCAmelCase__  :     int       	=   RagConfig(
			    retrieval_vector_size=self.retrieval_vector_size						,   question_encoder=DPRConfig().to_dict()						,   generator=BartConfig().to_dict()						,   index_name='''custom'''						,   )
			if from_disk:
					lowerCAmelCase__  :     str       	=   os.path.join(self.tmpdirname						,   '''dataset'''						)
					lowerCAmelCase__  :     Optional[int]       	=   os.path.join(self.tmpdirname						,   '''index.faiss'''						)
					dataset.get_index('''embeddings'''						).save(os.path.join(self.tmpdirname						,   '''index.faiss'''						)						)
					dataset.drop_index('''embeddings'''						)
					dataset.save_to_disk(os.path.join(self.tmpdirname						,   '''dataset'''						)						)
					del dataset
					lowerCAmelCase__  :     int       	=   RagPyTorchDistributedRetriever(
					    _SCREAMING_SNAKE_CASE						,   question_encoder_tokenizer=self.get_dpr_tokenizer()						,   generator_tokenizer=self.get_bart_tokenizer()						,   )
			else:
					lowerCAmelCase__  :     Optional[int]       	=   RagPyTorchDistributedRetriever(
					    _SCREAMING_SNAKE_CASE						,   question_encoder_tokenizer=self.get_dpr_tokenizer()						,   generator_tokenizer=self.get_bart_tokenizer()						,   index=CustomHFIndex(config.retrieval_vector_size						,   _SCREAMING_SNAKE_CASE						)						,   )
			if init_retrieval:
					retriever.init_retrieval(_SCREAMING_SNAKE_CASE						)
			return retriever




	def 				UpperCAmelCase__(   self		:						List[str]						,   _SCREAMING_SNAKE_CASE		:						bool						,   _SCREAMING_SNAKE_CASE		:						bool						)->			str:
			# Have to run in local mode because sys.path modifications at top of
			# file are not propogated to remote workers.
			# https://stackoverflow.com/questions/54338013/parallel-import-a-python-file-from-sibling-folder
			ray.init(local_mode=_SCREAMING_SNAKE_CASE						)
			lowerCAmelCase__  :     List[Any]       	=   self.get_dummy_dataset()
			lowerCAmelCase__  :     Union[str, Any]       	=   RagConfig(
			    retrieval_vector_size=self.retrieval_vector_size						,   question_encoder=DPRConfig().to_dict()						,   generator=BartConfig().to_dict()						,   index_name='''custom'''						,   )
			lowerCAmelCase__  :     int       	=   ray.remote(_SCREAMING_SNAKE_CASE						)
			lowerCAmelCase__  :     Any       	=   [remote_cls.remote() for _ in range(1						)]
			if from_disk:
					lowerCAmelCase__  :     List[Any]       	=   os.path.join(self.tmpdirname						,   '''dataset'''						)
					lowerCAmelCase__  :     int       	=   os.path.join(self.tmpdirname						,   '''index.faiss'''						)
					dataset.get_index('''embeddings'''						).save(os.path.join(self.tmpdirname						,   '''index.faiss'''						)						)
					dataset.drop_index('''embeddings'''						)
					dataset.save_to_disk(os.path.join(self.tmpdirname						,   '''dataset'''						)						)
					del dataset
					lowerCAmelCase__  :     Dict       	=   RagRayDistributedRetriever(
					    _SCREAMING_SNAKE_CASE						,   question_encoder_tokenizer=self.get_dpr_tokenizer()						,   generator_tokenizer=self.get_bart_tokenizer()						,   retrieval_workers=_SCREAMING_SNAKE_CASE						,   index=CustomHFIndex.load_from_disk(
					        vector_size=config.retrieval_vector_size						,   dataset_path=config.passages_path						,   index_path=config.index_path						,   )						,   )
			else:
					lowerCAmelCase__  :     List[Any]       	=   RagRayDistributedRetriever(
					    _SCREAMING_SNAKE_CASE						,   question_encoder_tokenizer=self.get_dpr_tokenizer()						,   generator_tokenizer=self.get_bart_tokenizer()						,   retrieval_workers=_SCREAMING_SNAKE_CASE						,   index=CustomHFIndex(config.retrieval_vector_size						,   _SCREAMING_SNAKE_CASE						)						,   )
			if init_retrieval:
					retriever.init_retrieval()
			return retriever




	def 				UpperCAmelCase__(   self		:						Dict						,   _SCREAMING_SNAKE_CASE		:						RagRetriever						,   _SCREAMING_SNAKE_CASE		:						np.array						,   _SCREAMING_SNAKE_CASE		:						int						)->			None:
			lowerCAmelCase__	,      lowerCAmelCase__	,      lowerCAmelCase__  :     Optional[int]       	=   retriever.retrieve(_SCREAMING_SNAKE_CASE						,   n_docs=_SCREAMING_SNAKE_CASE						)
			self.assertEqual(retrieved_doc_embeds.shape						,   (2, n_docs, self.retrieval_vector_size)						)
			self.assertEqual(len(_SCREAMING_SNAKE_CASE						)						,   2						)
			self.assertEqual(sorted(doc_dicts[0]						)						,   ['''embeddings''', '''id''', '''text''', '''title''']						)
			self.assertEqual(len(doc_dicts[0]['''id''']						)						,   _SCREAMING_SNAKE_CASE						)
			self.assertEqual(doc_dicts[0]['''id'''][0]						,   '''1'''						)  # max inner product is reached with second doc
			self.assertEqual(doc_dicts[1]['''id'''][0]						,   '''0'''						)  # max inner product is reached with first doc
			self.assertListEqual(doc_ids.tolist()						,   [[1], [0]]						)




	def 				UpperCAmelCase__(   self		:						Dict						)->			Any:
			lowerCAmelCase__  :     List[str]       	=   1
			lowerCAmelCase__  :     Dict       	=   np.array(
			    [np.ones(self.retrieval_vector_size						), -np.ones(self.retrieval_vector_size						)]						,   dtype=np.floataa						)

			self.distributed_retriever_check(
			    self.get_dummy_pytorch_distributed_retriever(init_retrieval=_SCREAMING_SNAKE_CASE						)						,   _SCREAMING_SNAKE_CASE						,   _SCREAMING_SNAKE_CASE						)




	def 				UpperCAmelCase__(   self		:						Dict						)->			Optional[int]:
			lowerCAmelCase__  :     Optional[Any]       	=   1
			lowerCAmelCase__  :     Tuple       	=   np.array(
			    [np.ones(self.retrieval_vector_size						), -np.ones(self.retrieval_vector_size						)]						,   dtype=np.floataa						)

			self.distributed_retriever_check(
			    self.get_dummy_custom_hf_index_pytorch_retriever(init_retrieval=_SCREAMING_SNAKE_CASE						,   from_disk=_SCREAMING_SNAKE_CASE						)						,   _SCREAMING_SNAKE_CASE						,   _SCREAMING_SNAKE_CASE						,   )




	def 				UpperCAmelCase__(   self		:						Dict						)->			Tuple:
			lowerCAmelCase__  :     List[Any]       	=   1
			lowerCAmelCase__  :     Any       	=   np.array(
			    [np.ones(self.retrieval_vector_size						), -np.ones(self.retrieval_vector_size						)]						,   dtype=np.floataa						)

			self.distributed_retriever_check(
			    self.get_dummy_custom_hf_index_pytorch_retriever(init_retrieval=_SCREAMING_SNAKE_CASE						,   from_disk=_SCREAMING_SNAKE_CASE						)						,   _SCREAMING_SNAKE_CASE						,   _SCREAMING_SNAKE_CASE						,   )




	@require_ray
	def 				UpperCAmelCase__(   self		:						List[Any]						)->			Any:
			lowerCAmelCase__  :     Any       	=   1
			lowerCAmelCase__  :     int       	=   np.array(
			    [np.ones(self.retrieval_vector_size						), -np.ones(self.retrieval_vector_size						)]						,   dtype=np.floataa						)

			self.distributed_retriever_check(
			    self.get_dummy_ray_distributed_retriever(init_retrieval=_SCREAMING_SNAKE_CASE						)						,   _SCREAMING_SNAKE_CASE						,   _SCREAMING_SNAKE_CASE						)
			ray.shutdown()




	@require_ray
	def 				UpperCAmelCase__(   self		:						List[str]						)->			List[Any]:
			lowerCAmelCase__  :     List[str]       	=   1
			lowerCAmelCase__  :     Union[str, Any]       	=   np.array(
			    [np.ones(self.retrieval_vector_size						), -np.ones(self.retrieval_vector_size						)]						,   dtype=np.floataa						)
			with self.assertRaises(_SCREAMING_SNAKE_CASE						):
					self.distributed_retriever_check(
					    self.get_dummy_custom_hf_index_ray_retriever(init_retrieval=_SCREAMING_SNAKE_CASE						,   from_disk=_SCREAMING_SNAKE_CASE						)						,   _SCREAMING_SNAKE_CASE						,   _SCREAMING_SNAKE_CASE						,   )
			ray.shutdown()




	@require_ray
	def 				UpperCAmelCase__(   self		:						Optional[Any]						)->			List[Any]:
			lowerCAmelCase__  :     Tuple       	=   1
			lowerCAmelCase__  :     Tuple       	=   np.array(
			    [np.ones(self.retrieval_vector_size						), -np.ones(self.retrieval_vector_size						)]						,   dtype=np.floataa						)

			self.distributed_retriever_check(
			    self.get_dummy_custom_hf_index_ray_retriever(init_retrieval=_SCREAMING_SNAKE_CASE						,   from_disk=_SCREAMING_SNAKE_CASE						)						,   _SCREAMING_SNAKE_CASE						,   _SCREAMING_SNAKE_CASE						)
			ray.shutdown()








from __future__ import annotations

from string import ascii_letters






def 	lowerCamelCase_       (			_a      ,  _a      ,  _a = None			):




		"""simple docstring"""






		lowerCAmelCase__  :     List[Any]       	=   alphabet or ascii_letters

		# The final result string
		lowerCAmelCase__  :     Optional[Any]       	=   ''''''

		for character in input_string:
				if character not in alpha:
						# Append without encryption if character is not in the alphabet
						result += character
				else:
						# Get the index of the new key and make sure it isn't too large
						lowerCAmelCase__  :     int       	=   (alpha.index(_a			) + key) % len(_a			)

						# Append the encoded character to the alphabet
						result += alpha[new_key]

		return result






def 	lowerCamelCase_       (			_a      ,  _a      ,  _a = None			):




		"""simple docstring"""






		key *= -1

		return encrypt(_a      ,  _a      ,  _a			)






def 	lowerCamelCase_       (			_a      ,  _a = None			):




		"""simple docstring"""






		lowerCAmelCase__  :     Optional[Any]       	=   alphabet or ascii_letters

		# To store data on all the combinations
		lowerCAmelCase__  :     Optional[int]       	=   {}

		# Cycle through each combination
		for key in range(1      ,  len(_a			) + 1			):
				# Decrypt the message and store the result in the data
				lowerCAmelCase__  :     Optional[int]       	=   decrypt(_a      ,  _a      ,  _a			)

		return brute_force_data


if __name__ == "__main__":
		while True:
				print(f'''\n{"-" * 10}\n Menu\n{"-" * 10}''')
				print(*['''1.Encrypt''', '''2.Decrypt''', '''3.BruteForce''', '''4.Quit'''], sep='''\n''')

				# get user input
				lowerCamelCase		=						input('''\nWhat would you like to do?: ''').strip() or '''4'''

				# run functions based on what the user chose
				if choice not in ("1", "2", "3", "4"):
						print('''Invalid choice, please enter a valid choice''')
				elif choice == "1":
						lowerCamelCase		=						input('''Please enter the string to be encrypted: ''')
						lowerCamelCase		=						int(input('''Please enter off-set: ''').strip())

						print(encrypt(input_string, key))
				elif choice == "2":
						lowerCamelCase		=						input('''Please enter the string to be decrypted: ''')
						lowerCamelCase		=						int(input('''Please enter off-set: ''').strip())

						print(decrypt(input_string, key))
				elif choice == "3":
						lowerCamelCase		=						input('''Please enter the string to be decrypted: ''')
						lowerCamelCase		=						brute_force(input_string)

						for key, value in brute_force_data.items():
								print(f'''Key: {key} | Message: {value}''')

				elif choice == "4":
						print('''Goodbye.''')
						break




