package com.atlassian.bitbucket.internal.branch.model.matchers;

import com.atlassian.bitbucket.branch.model.BranchType;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;

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

import static org.hamcrest.Matchers.is;
import static org.mockito.internal.util.Checks.checkNotNull;

public class BranchTypeMatchers {

    private BranchTypeMatchers() {
        throw new UnsupportedOperationException(BranchTypeMatchers.class.getName()
                + " should not be instantiated");
    }

    @Nonnull
    public static <BT extends BranchType> Matcher<BT> withId(@Nonnull Class<BT> targetType,
                                                             @Nullable String expectedId) {
        return withIdThat(targetType, is(expectedId));
    }

    @Nonnull
    public static <BT extends BranchType> Matcher<BT> withIdThat(@Nonnull Class<BT> targetType,
                                                                 @Nonnull Matcher<String> idMatcher) {
        checkNotNull(targetType, "targetType");
        return new FeatureMatcher<BT, String>(idMatcher, "branch type ID", "id") {

            @Override
            protected String featureValueOf(BT actual) {
                return actual.getId();
            }
        };
    }

    @Nonnull
    public static <BT extends BranchType> Matcher<BT> withDisplayName(@Nonnull Class<BT> targetType,
                                                                      @Nullable String expectedName) {
        return withDisplayNameThat(targetType, is(expectedName));
    }

    @Nonnull
    public static <BT extends BranchType> Matcher<BT> withDisplayNameThat(@Nonnull Class<BT> targetType,
                                                                          @Nonnull Matcher<String> nameMatcher) {
        checkNotNull(targetType, "targetType");
        return new FeatureMatcher<BT, String>(nameMatcher, "branch type display name", "displayName") {

            @Override
            protected String featureValueOf(BT actual) {
                return actual.getDisplayName();
            }
        };
    }
}
