from threading import Lock

from plesk_mail_migrator.core.progress.backup.backup_progress import BackupProgress
from plesk_mail_migrator.utils.file_utils import write_json_file_consistent


class BackupProgressFile(BackupProgress):
    """Class to track progress of mail messages backup - put the progress to JSON file"""

    def __init__(self, filename):
        self._filename = filename
        self._lock = Lock()
        self._data = {}

    def set_step(self, step):
        """Set step of backup, which is currently executing (see STEP_* constants)

        :type step: str | unicode
        :rtype: None
        """
        with self._lock:
            self._data['step'] = step
            self._write()

    def set_error(self, error_id, error_message):
        """Set error which occurred during backup

        Use ERROR_* constants for error ID, and comprehensive human-readable error message.

        :type error_id: str | unicode
        :type error_message: str | unicode
        :rtype: None
        """
        with self._lock:
            self._data['error_id'] = error_id
            self._data['error_message'] = error_message
            self._write()

    def _write(self):
        write_json_file_consistent(self._filename, self._data)

    def set_imap_vendor(self, imap_vendor):
        """Set IMAP vendor name in backup progress file

        :type imap_vendor: str | unicode
        :rtype: None
        """
        with self._lock:
            self._data['imap_vendor'] = imap_vendor
            self._write()

    def set_imap_host_detection_method(self, method):
        """Set identifier of a method which actually detected IMAP host

        Check plesk_mail_migrator.providers.imap.server_detect.detect for more details.

        :rtype: None
        """
        with self._lock:
            self._data['imap_host_detection_method'] = method
            self._write()

    def set_autodetected_imap_host(self, imap_host):
        """Set hostname of automatically detected IMAP host

        Check plesk_mail_migrator.providers.imap.server_detect.detect for more details.

        :type imap_host: str | unicode
        :rtype: None
        """
        with self._lock:
            self._data['autodetected_imap_host'] = imap_host
            self._write()
