package ru.yandex.qe.dispenser.ws;

import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import io.swagger.annotations.Api;
import io.swagger.annotations.Authorization;
import org.jetbrains.annotations.Nullable;

import ru.yandex.qe.dispenser.api.v1.DiPermission;
import ru.yandex.qe.dispenser.domain.Person;
import ru.yandex.qe.dispenser.domain.hierarchy.Hierarchy;
import ru.yandex.qe.dispenser.domain.hierarchy.Role;
import ru.yandex.qe.dispenser.domain.hierarchy.Session;
import ru.yandex.qe.dispenser.swagger.DispenserSecurityDefinition;
import ru.yandex.qe.dispenser.swagger.SwaggerTags;
import ru.yandex.qe.dispenser.ws.quota.request.workflow.ResourceWorkflow;

import static ru.yandex.qe.dispenser.ws.quota.request.workflow.ResourceWorkflow.isUserProcessResponsibleOrProvidersAdmin;
import static ru.yandex.qe.dispenser.ws.aspect.AccessAspect.isDispenserAdmin;

@Path("/v1/permission")
@Produces(ServiceBase.APPLICATION_JSON_UTF_8)
@org.springframework.stereotype.Service("permission")
@Api(tags = {SwaggerTags.DISPENSER_API}, authorizations = {@Authorization(value = DispenserSecurityDefinition.AUTHORIZATION_SCHEME_NAME)})
public class PermissionService {

    private static final String LOGIN_PARAM = "login";

    @GET
    @Access
    public DiPermission getPersonInfo(@QueryParam(LOGIN_PARAM) @Nullable final Person personFromQueryParam) {
        final Person person = Optional.ofNullable(personFromQueryParam).orElse(Session.WHOAMI.get());

        return DiPermission.builder()
                .login(person.getLogin())
                .permissionSet(permissionsForPerson(person))
                .build();
    }

    public static boolean canUserViewProviderGroupReport(final Person person) {
        return isUserProcessResponsibleOrProvidersAdmin(person)
                || isDispenserAdmin(person)
                || !Hierarchy.get().getPersonReader().getLinkedProjects(person, Role.RESPONSIBLE).isEmpty();
    }

    private Set<DiPermission.Permission> permissionsForPerson(final Person person) {
        final EnumSet<DiPermission.Permission> permissions = EnumSet.noneOf(DiPermission.Permission.class);

        if (canUserViewProviderGroupReport(person)) {
            permissions.add(DiPermission.Permission.CAN_VIEW_PROVIDER_GROUP_REPORT);
        }
        if (ResourceWorkflow.canUserViewMoney(person)) {
            permissions.add(DiPermission.Permission.CAN_VIEW_OWNING_COST);
        }

        return permissions;
    }
}
