package com.atlassian.stash.internal.maintenance;

import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.stash.internal.maintenance.latch.Latch;
import com.atlassian.stash.internal.maintenance.latch.LatchableService;
import org.springframework.aop.support.AopUtils;

/**
 * Base class for constructing tasks that unlatch resources
 *
 * @since 3.4
 */
public abstract class AbstractUnlatchTask<L extends Latch> extends AbstractMaintenanceTask {

    protected final I18nService i18nService;

    private final LatchableService<L> latchableService;

    private volatile boolean unlatched;

    protected AbstractUnlatchTask(I18nService i18nService, LatchableService<L> latchableService) {
        this.i18nService = i18nService;
        this.latchableService = latchableService;
    }

    @Override
    public void run() {
        if (unlatched) {
            throw new IllegalStateException(getTypeName() + " already unlatched");
        }

        L latch = latchableService.getCurrentLatch();
        if (latch == null) {
            throw new IllegalStateException(getTypeName() + " not latched");
        }
        unlatch(latch);

        unlatched = true;
    }

    protected void unlatch(L latch) {
        latch.unlatch();
    }

    protected boolean isUnlatched() {
        return unlatched;
    }

    private String getTypeName() {
        return AopUtils.getTargetClass(latchableService).getSimpleName();
    }
}
