package com.atlassian.bitbucket.mesh.test.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotates a field on a test class into which a {@code Repository} should be injected.
 * <p>
 * <b>This annotation can only be applied to {@code Repository} fields.</b> Annotated fields will be injected with a
 * constructed {@code Repository} (<i>not a mock!</i>) which will have all of its properties set in a valid way and
 * an ID which corresponds to the location where the data was unpacked. Tests then use {@code Repository#getPath} just
 * as production code would for for locating and interacting with repository data.
 * <p>
 * A default repository is made available by the underlying testing infrastructure. The default repository is very
 * simple, which means it may not be appropriate for all tests, but it's also very stable, so tests which use it are
 * unlikely to break due to data changes.
 * <p>
 * This annotation is intended as a simplification for building unit tests which operate on real repository data. The
 * underlying support classes automatically manage unpacking, caching and cleanup to ensure the tests run as quickly
 * as possible in terms of their setup and teardown. Rather than writing redundant initialization code, be it in each
 * test, in a helper method or in an {@code &#064;Before}-annotated method, just annotate the field.
 *
 * @see DirtiesRepo
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Repo {

    /**
     * Defines the path to the zip file containing the repository. The specified path is expected to be a valid
     * Spring {@code Resource} path. The test {@code ApplicationContext} will be used to resolve the value to a
     * {@code Resource} of the correct type.
     *
     * @return the resource path to the repository, or {@code "default"} to inject the default repository
     */
    String value() default "default";

    /**
     * Defines what format the repository should be created as, or more specifically, what type of data store
     * should be used to create the repository.
     *
     * @return the type of repository
     */
    Type type() default Type.MANAGED;

    enum Type {
        BITBUCKET_SERVER,
        MANAGED,
        PATH
    }
}
