package org.exoplatform.cs.rest.utils;

import org.exoplatform.commons.utils.CommonsUtils;
import org.exoplatform.commons.utils.ListAccess;
import org.exoplatform.commons.utils.PropertyManager;
import org.exoplatform.cs.dto.SpaceDTO;
import org.exoplatform.cs.rest.model.CSpace;
import org.exoplatform.cs.rest.model.Ticket;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.OrganizationService;
import org.exoplatform.services.organization.User;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.IdentityConstants;
import org.exoplatform.social.core.identity.model.Identity;
import org.exoplatform.social.core.identity.model.Profile;
import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider;
import org.exoplatform.social.core.manager.IdentityManager;
import org.exoplatform.social.core.space.model.Space;
import org.exoplatform.social.core.space.spi.SpaceService;
import org.exoplatform.web.CacheUserProfileFilter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CSRestUtils {
    private static final String SUPPORT_GROUP_NAME_CONFIGURATION = "exo.addon.cs.support.group.name";
    private static final String ADMINS_GROUP = "/platform/administrators";
    private static final Log LOG = ExoLogger.getLogger(CSRestUtils.class);

    public static User getCurrentUser() throws Exception {
        OrganizationService organizationService = CommonsUtils.getOrganizationService();
        if (ConversationState.getCurrent() == null || ConversationState.getCurrent().getIdentity() == null
                || ConversationState.getCurrent().getIdentity().getUserId() == null
                || ConversationState.getCurrent().getIdentity().getUserId().equals(IdentityConstants.SYSTEM)) {
            throw new IllegalStateException("Current user not found.");
        }
        User user = (User) ConversationState.getCurrent().getAttribute(CacheUserProfileFilter.USER_PROFILE);
        if (user == null) {
            String userId = ConversationState.getCurrent().getIdentity().getUserId();
            user = organizationService.getUserHandler().findUserByName(userId);
        }
        return user;
    }

    public static final Profile getProfile(String userName) throws Exception {
        IdentityManager identityManager = CommonsUtils.getService(IdentityManager.class);
        Identity identity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, userName);
        Profile profile = identity.getProfile();
        return profile;
    }

    public static String getSupportMemberGroupName() {
        String groupId = PropertyManager.getProperty(SUPPORT_GROUP_NAME_CONFIGURATION);
        if (groupId == null || groupId.isEmpty()) {
            groupId = "support-team";
        }
        return "/" + groupId;
    }

    public static List<User> getSupportMembers() {
        OrganizationService organizationService = CommonsUtils.getService(OrganizationService.class);
        String supportGroup = getSupportMemberGroupName();
        try {
            ListAccess<User> engSupportList = organizationService.getUserHandler().findUsersByGroupId(supportGroup);
            User[] users = engSupportList.load(0, engSupportList.getSize());
            return Arrays.asList(users);
        } catch (Exception e) {
            LOG.warn("Cannot get the list of group members");
            return new ArrayList<User>();
        }
    }

    public static boolean isSupportMember() {
        return ConversationState.getCurrent().getIdentity().isMemberOf(getSupportMemberGroupName());
    }

    public static CSpace extendCSSpace(CSpace cSpace) {
        SpaceService spaceService = CommonsUtils.getService(SpaceService.class);
        Space space = spaceService.getSpaceByGroupId(cSpace.getGroupId());
        cSpace.setAvatarUrl(space.getAvatarUrl());
        return cSpace;
    }

    public static final boolean canManage() {
        return ConversationState.getCurrent().getIdentity().isMemberOf(ADMINS_GROUP)
                || isSupportMember();
    }

    public static final boolean authorizedOnCS(String spaceGroupId)  {
        SpaceService spaceService = CommonsUtils.getService(SpaceService.class);
        Space currCS = spaceService.getSpaceByGroupId(spaceGroupId);
        try {
            return spaceService.isMember(currCS, getCurrentUser().getUserName())
                    || spaceService.isSuperManager(getCurrentUser().getUserName());
        } catch (Exception e) {
            LOG.error("error while checking authorization on the customer space", e);
        }
        return false;
    }
}
