package org.jenkinsci.plugins.saml;

import hudson.Extension;
import hudson.model.AsyncAperiodicWork;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * <p>This periodic work update the IdP Metadata File, the periodicof the execution is defined on the SAML Plugin configuration.</p>
 * <p>If the Preriod is set to 0 the Periodic work is mostly disabled, it will check the changes on config
 * every 10 minutes to see if it is enabled again, if the period change it is re-enabled again.</p>
 */
@Extension
public class UpdateMetadataFromURLPeriodicWork extends AsyncAperiodicWork {
    private static final Logger LOG = Logger.getLogger(UpdateMetadataFromURLPeriodicWork.class.getName());
    private boolean scheduleedOnce;

    /**
     * {@inheritDoc}
     */
    public UpdateMetadataFromURLPeriodicWork() {
        super("Update IdP Metadata from URL PeriodicWork");
    }

    /**
     * @return the configured period, if the configured period is 0 return 10 minutes,
     * if we are starting the Jenkins instance schedule an execution after 10 seconds.
     */
    @Override
    public long getRecurrencePeriod() {
        long ret = getConfiguredPeriod();
        if (ret == 0) {
            ret = TimeUnit.MINUTES.toMillis(10);
        } else if (!scheduleedOnce){
            ret = 10000;
        }
        scheduleedOnce = true;
        return ret;
    }

    /**
     * @return check the configured period in the SAML Plugin configuration.
     */
    private long getConfiguredPeriod() {
        long ret = 0;
        jenkins.model.Jenkins j = jenkins.model.Jenkins.getInstance();
        if (j.getSecurityRealm() instanceof SamlSecurityRealm) {
            SamlSecurityRealm samlSecurityRealm = (SamlSecurityRealm) j.getSecurityRealm();
            IdpMetadataConfiguration config = samlSecurityRealm.getIdpMetadataConfiguration();
            if(config != null && config.getPeriod() != null && StringUtils.isNotBlank(config.getUrl())) {
                ret = TimeUnit.MINUTES.toMillis(config.getPeriod());
            }
        }
        return ret;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public hudson.model.AperiodicWork getNewInstance() {
        return new UpdateMetadataFromURLPeriodicWork();
    }

    /**
     * {@inheritDoc}
     * <p>Connect to the URL configured on the SAML configuration to get the IdP Metadata, then download it </p>
     * <p>if the period configured is 0 it returns directly, do nothing.</p>
     */
    @Override
    protected void execute(hudson.model.TaskListener listener) throws IOException, InterruptedException {
        if (getConfiguredPeriod() == 0) {
            return;
        }

        Jenkins j = Jenkins.getInstance();
        if (j.getSecurityRealm() instanceof SamlSecurityRealm) {
            SamlSecurityRealm samlSecurityRealm = (SamlSecurityRealm) j.getSecurityRealm();
            try {
                samlSecurityRealm.getIdpMetadataConfiguration().updateIdPMetadata();
            } catch (IOException | IllegalArgumentException e) {
                LOG.log(Level.SEVERE, e.getMessage(), e);
            }
        }
    }
}

@@ -852,38 +852,419 @@
     
-private boolean scheduleedOnce
+/**%0A     * property to set the initial delay of the AsyncAperiodicWork.%0A     * -Dorg.jenkinsci.plugins.saml.UpdateMetadataFromURLPeriodicWork.initialDelay=MILLISECONDS%0A     */%0A    public static final String INITIAL_DELAY_PROPERTY = UpdateMetadataFromURLPeriodicWork.class.getName() + %22.initialDelay%22;%0A    public static final long INITIAL_DELAY = Long.valueOf(System.getProperty(INITIAL_DELAY_PROPERTY, %2210000%22))
 ;%0A%0A 
@@ -1787,101 +1787,122 @@
    %7D
- else if (!scheduleedOnce)%7B
+%0A        return ret;
 %0A    
+%7D%0A%0A
     
-    ret = 10000;
+/**%0A     * %7B@inheritDoc%7D
 %0A     
-   %7D
+*/
 %0A    
-    scheduleedOnce = true;
+@Override%0A    public long getInitialDelay() %7B
 %0A   
@@ -1905,35 +1905,45 @@
 %0A        return 
-ret
+INITIAL_DELAY
 ;%0A    %7D%0A%0A    /**

change to use initial delay (#52)