import os
import shutil

from logging_handler import LoggerHandler
from error_handler import ExportErrorMessages


class FileManagementHandler:
    """
    class for handling file management during running export script

    """

    @staticmethod
    def remove_file(file_path):
        try:
            os.remove(file_path)
            LoggerHandler.print_message(f"File {file_path} removed successfully.")
        except OSError as e:
            raise Exception(f"Error removing file {file_path}: {str(e)}")

    @staticmethod
    def remove_dir(directory, folder_name):
        """
        This method removes folder_name under directory if this folder exist.

        :param directory: directory path (which include folder_name)
        :param folder_name: folder delete
        :return: remove the folder from a given directory
        """
        if FileManagementHandler.is_folder_in_directory(directory):
            LoggerHandler.print_message(f"The folder '{folder_name}' exists.")

            try:
                shutil.rmtree(directory)
                LoggerHandler.print_message(f"Directory '{directory}' successfully deleted.")

            except Exception as e:
                msg = f"{ExportErrorMessages.FAILED_TO_REMOVE_DIRECTORY.value} : '{folder_name}' under directory: " \
                      f"{directory}"
                raise Exception(msg + str(e))
        else:
            LoggerHandler.print_message(f"The folder '{folder_name}' does not exist under '{directory}'.")

    @staticmethod
    def is_folder_in_directory(folder_path):
        """
        This method returns whether some path exist with a folder.

        :param folder_path: The path to the directory
        :return: True if the folder exists, False otherwise.
        """
        return os.path.exists(folder_path) and os.path.isdir(folder_path)

    @staticmethod
    def create_folder(directory_path, folder_name):
        """
        This method creates folder_name under directory_path

        :param directory_path: The path to the directory
        :param folder_name: The folder name
        :return: create folder_name under directory_path
        """
        try:
            LoggerHandler.print_message(f"Creating folder '{folder_name}' under '{directory_path}'")
            file_path = os.path.join(directory_path, folder_name)
            os.makedirs(file_path)
            LoggerHandler.print_message(f"Directory '{file_path}' created successfully.")
        except Exception as e:
            msg = f"{ExportErrorMessages.FAILED_TO_CREATE_DIRECTORY.value} {directory_path} with folder name {folder_name}"
            raise Exception(msg + str(e))
            # LoggerHandler.print_message(f"Error creating directory '{file_path}': {e}")

    @staticmethod
    def create_file(directory, file_name, file_content):
        """
        This method creates file with file_name and file_content under directory path

        :param directory: The path to the directory
        :param file_name: The file name
        :param file_content: The content of the file we would like to create
        :return:
        """
        LoggerHandler.print_message(f"creating '{file_name}' file")
        # Join the directory path and file name to get the full file path
        file_path = os.path.join(directory, file_name)

        # Open the file in write mode and write "1.0" to it
        try:
            with open(file_path, 'w') as file:
                file.write(file_content)
        except Exception:
            msg = f"{Exception(ExportErrorMessages.FAILED_TO_CREATE_FILE.value)} file: '{file_name}'" \
                  f" under directory: '{directory}'"
            raise Exception(msg)
        LoggerHandler.print_message(f"File '{file_name}' created successfully in '{directory}'.")

    @staticmethod
    def copy_file(source_path, destination_path):
        """
        This method copy source_path to destination_path.

        :param source_path:  The source path to the directory
        :param destination_path: The destination path to the directory
        :return: copy source to destination
        """
        try:
            shutil.copy2(source_path, destination_path)
        except Exception as e:
            if not os.path.exists(destination_path):
                msg = f"{Exception(ExportErrorMessages.FAILED_TO_COPY_FILE.value)} + on destination: '{destination_path}'"
                raise Exception(msg + str(e))
