package com.atlassian.stash.internal.mode;

import com.atlassian.bitbucket.server.ApplicationMode;
import com.google.common.collect.Maps;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Map;

import static com.atlassian.stash.internal.ApplicationConstants.PROP_APPLICATION_MODE;

/**
 * Uses the {@link DefaultApplicationMode} and {@link MirrorApplicationMode} annotations to determine whether a component
 * is enabled for the current {@link ApplicationModeCondition application mode} or not.
 * <p/>
 * Note: If this condition is applied to a bean which is not annotated <i>the bean will not be loaded</i>.
 *
 * @see ApplicationMode
 * @see DefaultApplicationMode
 * @see MirrorApplicationMode
 */
public class ApplicationModeCondition implements Condition {
    private static final Map<ApplicationMode, String> modeMap = Maps.newHashMap();

    static {
        modeMap.put(ApplicationMode.DEFAULT, DefaultApplicationMode.class.getName());
        modeMap.put(ApplicationMode.MIRROR, MirrorApplicationMode.class.getName());
    }

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ApplicationMode mode = ApplicationMode
                .fromId(context.getEnvironment().getProperty(PROP_APPLICATION_MODE))
                .orElse(ApplicationMode.DEFAULT);
        String annotationName = modeMap.get(mode);
        return annotationName != null && metadata.isAnnotated(annotationName);
    }
}
