from threading import Lock

from application.service import LoaderUpdaterService
from application.model.configuration import Window
from application.repository.pos import LoaderUpdaterPOSRepository
from application.util import ValidationUtil


class RemoteLoaderUpdaterInteractor(object):
    def __init__(
        self,                       # type: RemoteLoaderUpdaterInteractor
        loader_updater_service,     # type: LoaderUpdaterService
        remote_update_window,       # type: Window
        working_on_update,          # type: Lock
        pos_repository,             # type: LoaderUpdaterPOSRepository
    ):
        # type: (...) -> None

        self.loader_updater_service = loader_updater_service
        self.remote_update_window = remote_update_window
        self.working_on_update = working_on_update
        self.pos_repository = pos_repository

    def update_loaders(
        self,                   # type: RemoteLoaderUpdaterInteractor
        external_update_id,     # type: str
    ):
        # type: (...) -> None

        inserted = self._insert_remote_update(external_update_id=external_update_id)
        if inserted and self._verify_update_window():
            self.loader_updater_service.update_loaders(restart_hv=True)

    def _insert_remote_update(
        self,                 # type: RemoteLoaderUpdaterInteractor
        external_update_id,   # type: str
    ):
        # type: (...) -> bool

        with self.working_on_update:
            last_loader_update_id = int(self.pos_repository.get_last_loader_update_param("UpdateId"))
            return self.pos_repository.insert_new_remote_loader_update(
                update_id=str(last_loader_update_id + 1),
                update_name="Loaders",
                external_update_id=external_update_id,
            )

    def _verify_update_window(
        self,   # type: RemoteLoaderUpdaterInteractor
    ):
        # type: (...) -> bool

        start_time = self.remote_update_window.start_time
        end_time = self.remote_update_window.end_time
        return ValidationUtil.is_inside_allowed_window(
            start_time=start_time,
            end_time=end_time,
        )
