package com.atlassian.bitbucket.hamcrest;

import com.atlassian.bitbucket.project.Project;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.bitbucket.permission.PermissionRequest;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;

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

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;

public class PermissionRequestMatchers {

    private PermissionRequestMatchers() {
        throw new UnsupportedOperationException("Do not instantiate " + getClass().getSimpleName());
    }

    @Nonnull
    public static Matcher<PermissionRequest> globalPermissionRequest(@Nonnull Permission permission) {
        return permissionRequestWith(permission, null);
    }

    @Nonnull
    public static Matcher<PermissionRequest> idPermissionRequest(@Nonnull Permission permission, int id) {
        return permissionRequestWith(permission, id);
    }

    @Nonnull
    public static Matcher<PermissionRequest> permissionRequestWith(@Nonnull Permission permission,
                                                                   @Nullable Object resource) {
        return permissionRequestWith(permission, resource, null);
    }

    @Nonnull
    public static Matcher<PermissionRequest> permissionRequestWith(@Nonnull Permission permission,
                                                                   @Nullable Object resource,
                                                                   @Nullable ApplicationUser user) {
        return allOf(withPermission(permission), withResource(resource), withUser(user));
    }

    @Nonnull
    public static Matcher<PermissionRequest> projectPermissionRequest(@Nonnull Permission permission,
                                                                      @Nonnull Project project) {
        return permissionRequestWith(permission, project);
    }

    @Nonnull
    public static Matcher<PermissionRequest> repositoryPermissionRequest(@Nonnull Permission permission,
                                                                         @Nonnull Repository repository) {
        return permissionRequestWith(permission, repository);
    }

    @Nonnull
    public static Matcher<PermissionRequest> withPermission(@Nonnull Permission permission) {
        return new FeatureMatcher<PermissionRequest, Permission>(is(permission), "permission", "permision") {
            @Override
            protected Permission featureValueOf(PermissionRequest actual) {
                return actual.getPermission();
            }
        };
    }

    @Nonnull
    public static Matcher<PermissionRequest> withResource(@Nullable Object resource) {
        return withResourceThat(is(resource));
    }

    @Nonnull
    public static Matcher<PermissionRequest> withResourceThat(@Nonnull Matcher<Object> resourceMatcher) {
        return new FeatureMatcher<PermissionRequest, Object>(resourceMatcher, "resource that", "resource") {
            @Override
            protected Object featureValueOf(PermissionRequest actual) {
                return actual.getResource();
            }
        };
    }

    @Nonnull
    public static Matcher<PermissionRequest> withUser(@Nullable ApplicationUser user) {
        return withUserThat(is(user));
    }

    @Nonnull
    public static Matcher<PermissionRequest> withUserThat(@Nonnull Matcher<ApplicationUser> userMatcher) {
        return new FeatureMatcher<PermissionRequest, ApplicationUser>(userMatcher, "user that", "user") {
            @Override
            protected ApplicationUser featureValueOf(PermissionRequest actual) {
                return actual.getUser();
            }
        };
    }
}
