package com.atlassian.bitbucket.rule;

import com.atlassian.bitbucket.annotation.FixedCurrentTime;
import org.joda.time.DateTimeUtils;
import org.junit.rules.ExternalResource;
import org.junit.runners.model.Statement;

/**
 * Sets current time to a fixed value for methods annotated with {@link FixedCurrentTime}.
 * This rule uses {@link DateTimeUtils} as time management mechanism.
 *
 * @see DateTimeUtils
 * @see org.joda.time.Instant
 */
public class FixedCurrentTimeRule extends ExternalResource {
    private final long fixedCurrentTime = System.currentTimeMillis();

    @Override
    public Statement apply(final Statement base, final org.junit.runner.Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                boolean needsFixedTime = description.getAnnotation(FixedCurrentTime.class) != null;
                if (needsFixedTime) {
                    DateTimeUtils.setCurrentMillisFixed(fixedCurrentTime);
                }
                try {
                    base.evaluate();
                } finally {
                    if (needsFixedTime) {
                        DateTimeUtils.setCurrentMillisSystem();
                    }
                }
            }
        };
    }

}
