package com.atlassian.bitbucket.scm;

import com.atlassian.plugin.Plugin;
import com.atlassian.plugin.PluginParseException;
import com.atlassian.plugin.module.ModuleFactory;
import com.atlassian.plugin.util.validation.ValidationPattern;
import org.dom4j.Element;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static com.atlassian.plugin.util.validation.ValidationPattern.test;

/**
 * A base class for constructing module descriptors for {@link ScmRequest} handlers.
 */
public abstract class AbstractScmRequestHandlerModuleDescriptor<T> extends BaseWeightedModuleDescriptor<T> {

    private String scm;
    private ScmUrlFormatterModuleDescriptor urlFormatterModuleDescriptor;

    public AbstractScmRequestHandlerModuleDescriptor(ModuleFactory moduleFactory, int defaultWeight) {
        super(moduleFactory, defaultWeight);
    }

    @Override
    public void init(@Nonnull Plugin plugin, @Nonnull Element element) throws PluginParseException {
        super.init(plugin, element);

        scm = element.attributeValue("scm");

        Element urlFormatterElement = element.element("url-formatter");
        if (urlFormatterElement != null) {
            urlFormatterModuleDescriptor = new ScmUrlFormatterModuleDescriptor(moduleFactory);
            urlFormatterModuleDescriptor.init(plugin, urlFormatterElement);
        }
    }

    @Nonnull
    @Override
    public T getModule() {
        return moduleFactory.createModule(moduleClassName, this);
    }

    /**
     * Retrieves the {@link Scm#getId() ID} of the SCM this handler adds support for, or {@code null} if
     * this handler does not, of itself, add support for any specific SCM.
     *
     * @return the SCM this handler adds support for, or {@code null}
     */
    @Nullable
    public String getScm() {
        return scm;
    }

    /**
     * Retrieves the {@link ScmUrlFormatter} which should be used to format clone URLs targeting this handler.
     * If no formatter is specified, a default URL will be generated.
     *
     * @return a URL formatter, or {@code null} to use the default URL
     */
    @Nullable
    public ScmUrlFormatter getUrlFormatter() {
        return urlFormatterModuleDescriptor == null ? null : urlFormatterModuleDescriptor.getModule();
    }

    @Override
    protected void provideValidationRules(ValidationPattern pattern) {
        super.provideValidationRules(pattern);

        pattern.rule(test("@class").withError("The ssh-request-handler class attribute is required"));
    }
}
