package com.atlassian.stash.internal.maintenance;

import com.hazelcast.core.*;

import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class HazelcastMaintenanceModeHelper implements MaintenanceModeHelper, ItemListener<JohnsonMaintenanceEvent> {

    private final Object lock = new Object();
    private final MaintenanceModeHelper localMaintenanceModeHelper;
    private final ISet<JohnsonMaintenanceEvent> maintenanceEvents;
    private String listenerRegistrationId;

    public HazelcastMaintenanceModeHelper(ISet<JohnsonMaintenanceEvent> maintenanceEvents,
                                          MaintenanceModeHelper localMaintenanceModeHelper) {
        this.localMaintenanceModeHelper = localMaintenanceModeHelper;
        this.maintenanceEvents = maintenanceEvents;
    }

    @PreDestroy
    public void destroy() {
        if (listenerRegistrationId != null) {
            maintenanceEvents.removeItemListener(listenerRegistrationId);
        }
    }

    @PostConstruct
    public void init() {
        synchronized (lock) {
            listenerRegistrationId = maintenanceEvents.addItemListener(this, true);

            for (JohnsonMaintenanceEvent event : maintenanceEvents) {
                localMaintenanceModeHelper.lock(event);
            }
        }
    }

    @Override
    public void itemAdded(ItemEvent<JohnsonMaintenanceEvent> item) {
        synchronized (lock) {
            localMaintenanceModeHelper.lock(item.getItem());
        }
    }

    @Override
    public void itemRemoved(ItemEvent<JohnsonMaintenanceEvent> item) {
        synchronized (lock) {
            localMaintenanceModeHelper.unlock(item.getItem());
        }
    }

    @Override
    public void lock(@Nonnull JohnsonMaintenanceEvent event) {
        maintenanceEvents.add(event);
    }

    @Override
    public void unlock(@Nonnull JohnsonMaintenanceEvent event) {
        maintenanceEvents.remove(event);
    }
}
