import datetime
import os


class CommonSessionFiles(object):
    """Common paths to files in migration session directory."""

    def __init__(self, conn, migrator_server):
        """
        :type conn: parallels.core.connections.connections.Connections
        :type migrator_server: parallels.core.connections.migrator_server.MigratorServer
        """
        self._conn = conn
        self._migrator_server = migrator_server
        self._time = datetime.datetime.now().strftime("%Y.%m.%d.%H.%M.%S")

    def is_file_exists(self, path):
        return self._migrator_server.session_dir.is_file_exists(path)

    def read_file(self, path):
        return self._migrator_server.session_dir.read_file(path)

    def write_file(self, path, content):
        self._migrator_server.session_dir.write_file(path, content)

    def get_file_path(self, *args):
        return self._migrator_server.session_dir.get_file_path(*args)

    def get_file(self, *args):
        """
        :rtype: parallels.core.session_files.SessionFile
        """
        return SessionFile(self, self.get_file_path(*args))

    def get_cache_state_controllers_data_file(self):
        return self.get_file(u'cache-state-controllers-data.json')

    def get_raw_dump_filename(self, source_id):
        return self.get_file_path(u"plesk.backup.%s.raw.%s" % (source_id, self._get_dump_extension()))

    def get_downloaded_dump_filename(self, source_id):
        return self.get_file_path(u"plesk.backup.%s.downloaded.%s" % (source_id, self._get_dump_extension()))

    def get_dump_format_update_original_directory(self, source_id):
        return self.get_file_path(u"plesk.backup.%s.original" % source_id)

    def get_dump_format_update_converted_directory(self, source_id):
        return self.get_file_path(u"plesk.backup.%s.converted" % source_id)

    def get_upgraded_dump_filename(self, source_id):
        return self.get_file_path(u"plesk.backup.%s.upgraded.%s" % (source_id, self._get_dump_extension()))

    def get_path_to_raw_plesk_backup_selection(self, server_id):
        return self.get_file_path(u"plesk.backup.%s.selection.yaml" % server_id)

    def get_path_to_shallow_plesk_backup(self, server_id):
        return self.get_file_path(u"plesk.backup.%s.shallow.xml" % server_id)

    def get_path_to_cut_plesk_backup(self, source_id):
        return self.get_file_path(u"plesk.backup.%s.cut.%s" % (source_id, self._get_dump_extension()))

    def get_converted_dump_filename(self, source_id):
        return self.get_file_path(u"plesk.backup.%s.converted.%s" % (source_id, self._get_dump_extension()))

    def get_converted_dump_migration_list_filename(self, source_id):
        return self.get_file_path(u"%s.converted.migration-list" % source_id)

    def get_path_to_last_hosting_analysis_time(self):
        return self.get_file_path(u"last.hosting.analysis.time")

    def get_path_to_apache_restart_interval(self, ip=''):
        return self.get_file_path(u"apache_restart_interval_%s.yaml" % ip)

    def get_path_to_ssh_keys_pool(self):
        return self.get_file_path(u"ssh_key_pool.yaml")

    def get_path_to_info_log(self):
        return self.get_file_path(u"info.log")

    def get_path_to_debug_log(self):
        return self.get_file_path(u"debug.log")

    def get_path_to_binary_log_index(self):
        return self.get_file_path(u"binary_log.index")

    def get_path_to_binary_log_messages(self):
        return self.get_file_path(u"binary_log.messages")

    def get_path_to_task_manager_logs_dir(self):
        return self.get_file_path(u'tasks')

    def get_path_to_task_manager_runner_info_log(self):
        return os.path.join(self.get_path_to_task_manager_logs_dir(), u"runner.info.log")

    def get_path_to_task_manager_runner_debug_log(self):
        return os.path.join(self.get_path_to_task_manager_logs_dir(), u"runner.debug.log")

    def get_path_to_task_manager_info_log(self):
        return os.path.join(self.get_path_to_task_manager_logs_dir(), u"manager.info.log")

    def get_path_to_task_manager_debug_log(self):
        return os.path.join(self.get_path_to_task_manager_logs_dir(), u"manager.debug.log")

    def get_path_to_config_file(self):
        return self.get_file_path(u"config.ini")

    def get_path_to_progress(self):
        return self.get_file_path(u"progress")

    def get_path_to_subscriptions_status(self):
        return self.get_file_path(u'subscriptions-status.json')

    def get_path_to_subscriptions_report(self):
        return self.get_file_path(u'subscriptions-report.json')

    def get_path_to_target_model(self):
        return self.get_file_path(u"target.yaml")

    def get_path_to_existing_objects_model(self):
        return self.get_file_path(u"existing-objects.yaml")

    def get_path_to_default_migration_list_file(self):
        return self.get_file_path(u"migration-list")

    def get_path_to_default_ip_mapping_file(self):
        return self.get_file_path(u"ip-mapping")

    def get_path_to_generated_passwords(self):
        return self.get_file_path(u"generated-passwords.yaml")

    def get_path_to_migration_agent(self, ip):
        return self.get_file_path(u"migration_agent_path_%s" % ip)

    def get_path_to_rsync(self):
        return self.get_file_path(u"rsync_path_")

    def get_path_to_ips_list(self):
        return self.get_file_path(u"ips-list.json")

    def get_path_to_failed_subscriptions_list(self):
        return self.get_file_path(u"failed-subscriptions.%s" % self._time)

    def get_path_to_successful_subscriptions_list(self):
        return self.get_file_path(u"successful-subscriptions.%s" % self._time)

    def get_path_to_list_of_mssql_servers_with_no_physical_access(self):
        return self.get_file_path(u"mssql-servers-with-no-physical-access.json")

    def get_path_to_pmm_agent_dir(self):
        return self.get_file_path(u"pmm-agent.%s" % self._time)

    def get_lock_dir(self):
        return self.get_file_path(u"locks")

    def get_default_stop_mark_file(self):
        return self.get_file_path(u"stop")

    def get_path_to_migration_report(self):
        return self.get_file_path(u"migration-report.json")

    def get_agent_config_file(self, source_id):
        """
        :type source_id: str | unicode
        :rtype: parallels.core.session_files.SessionFile
        """
        return self.get_file(u"agent-config.%s.json" % source_id)

    def get_target_output_dir(self, source_id):
        """
        :type source_id: str | unicode
        :rtype: str | unicode
        """
        return self.get_file_path(u"output.%s.%s" % (source_id, self._time))

    def get_hosting_description_file(self, source_id, hosting_description_format):
        """
        :type source_id: str | unicode
        :type hosting_description_format: str | unicode
        :rtype: str | unicode
        """
        return self.get_file_path(u"hosting-description.%s.%s" % (source_id, hosting_description_format))

    def get_path_to_name_mapping(self):
        """
        :rtype: str | unicode
        """
        return self.get_file_path(u"name-mapping.yaml")

    def _get_dump_extension(self):
        return u"zip" if self._conn.target.is_windows else u"tar"


class SessionFile(object):
    def __init__(self, session_files, file_path):
        """
        :type session_files: parallels.core.session_files.CommonSessionFiles
        :type file_path: str
        """
        self._session_files = session_files
        self._file_path = file_path

    def is_exists(self):
        """
        :rtype: bool
        """
        return self._session_files.is_file_exists(self._file_path)

    def read(self):
        """
        :rtype: str | unicode
        """
        if not self.is_exists():
            return ''
        return self._session_files.read_file(self._file_path)

    def write(self, content):
        """
        :type content: str | unicode
        :rtype: None
        """
        self._session_files.write_file(self._file_path, content)

    @property
    def path(self):
        """Full path to the file

        :rtype: str | unicode
        """
        return self._file_path
