import threading

from parallels.core import messages
from parallels.core.logging import get_logger
from parallels.core.utils.common import default
from parallels.core.utils.common_constants import LOCK_SUBSCRIPTIONS_REPORT
from parallels.core.utils.json_utils import read_json, write_json
from parallels.core.utils.locks.session_file_lock import SessionFileLock
from parallels.core.utils.subscription_operations import SubscriptionOperation

logger = get_logger(__name__)


class SessionSubscriptionsReport(object):
    """File with per-session report of each subscription"""

    def __init__(self, filename):
        self._filename = filename
        self._update_thread_lock = threading.Lock()
        self._update_process_lock = SessionFileLock(LOCK_SUBSCRIPTIONS_REPORT)

    def set_operation_messages(self, subscription_name, operation, messages):
        with self._update_thread_lock:
            self._update_process_lock.acquire_block()
            try:
                self._load()
                self._reset_subscription_dict(subscription_name)
                self._data[subscription_name][operation] = messages
                self._save()
            finally:
                self._update_process_lock.release()

    def _load(self):
        try:
            self._data = default(read_json(self._filename), {})
        except Exception as e:
            logger.exception()
            logger.fwarn(messages.ERROR_READING_SUBSCRIPTION_STATUS, filename=self._filename, reason=e)
            self._data = {}

    def _save(self):
        write_json(self._filename, self._data, pretty_print=True)

    def _reset_subscription_dict(self, subscription_name):
        self._data[subscription_name] = {
            SubscriptionOperation.OPERATION_MIGRATED: [],
            SubscriptionOperation.OPERATION_CONTENT_SYNCED: [],
            SubscriptionOperation.OPERATION_DNS_SWITCHED: [],
        }
