// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.projects;

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.inject.Inject;
import javax.mail.MessagingException;
import javax.naming.ConfigurationException;

import com.cloud.resourcelimit.CheckedReservation;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ProjectRole;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.acl.dao.ProjectRoleDao;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.reservation.dao.ReservationDao;
import org.apache.cloudstack.utils.mailing.MailAddress;
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
import org.apache.cloudstack.webhook.WebhookHelper;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.stereotype.Component;

import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.ProjectAccountJoinDao;
import com.cloud.api.query.dao.ProjectInvitationJoinDao;
import com.cloud.api.query.dao.ProjectJoinDao;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcManager;
import com.cloud.projects.Project.State;
import com.cloud.projects.ProjectAccount.Role;
import com.cloud.projects.dao.ProjectAccountDao;
import com.cloud.projects.dao.ProjectDao;
import com.cloud.projects.dao.ProjectInvitationDao;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.DomainManager;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;

@Component
public class ProjectManagerImpl extends ManagerBase implements ProjectManager, Configurable {

    private static final SecureRandom secureRandom = new SecureRandom();

    @Inject
    private DomainDao _domainDao;
    @Inject
    private ProjectDao _projectDao;
    @Inject
    private ProjectJoinDao _projectJoinDao;
    @Inject
    AccountManager _accountMgr;
    @Inject
    DomainManager _domainMgr;
    @Inject
    ConfigurationManager _configMgr;
    @Inject
    ResourceLimitService _resourceLimitMgr;
    @Inject
    private ProjectAccountDao _projectAccountDao;
    @Inject
    private ProjectAccountJoinDao _projectAccountJoinDao;
    @Inject
    private AccountDao _accountDao;
    @Inject
    private ConfigurationDao _configDao;
    @Inject
    private ProjectInvitationDao _projectInvitationDao;
    @Inject
    private ProjectInvitationJoinDao _projectInvitationJoinDao;
    @Inject
    protected ResourceTagDao _resourceTagDao;
    @Inject
    private ProjectRoleDao projectRoleDao;
    @Inject
    private UserDao userDao;
    @Inject
    private VolumeDao _volumeDao;
    @Inject
    private UserVmDao _userVmDao;
    @Inject
    private VMTemplateDao _templateDao;
    @Inject
    private NetworkDao _networkDao;
    @Inject
    private VMSnapshotDao _vmSnapshotDao;
    @Inject
    private VpcManager _vpcMgr;
    @Inject
    MessageBus messageBus;
    @Inject
    private ReservationDao reservationDao;

    protected boolean _invitationRequired = false;
    protected long _invitationTimeOut = 86400000;
    protected boolean _allowUserToCreateProject = true;
    protected ScheduledExecutorService _executor;
    protected int _projectCleanupExpInvInterval = 60; //Interval defining how often project invitation cleanup thread is running
    private String senderAddress;
    protected SMTPMailSender mailSender;

    protected List<? extends ControlledEntity> listWebhooksForProject(Project project) {
        List<? extends ControlledEntity> webhooks = new ArrayList<>();
        try {
            WebhookHelper webhookService = ComponentContext.getDelegateComponentOfType(WebhookHelper.class);
            webhooks = webhookService.listWebhooksByAccount(project.getProjectAccountId());
        } catch (NoSuchBeanDefinitionException ignored) {
            logger.debug("No WebhookHelper bean found");
        }
        return webhooks;
    }

    @Override
    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {

        Map<String, String> configs = _configDao.getConfiguration(params);
        _invitationRequired = ProjectInviteRequired.value();
        _invitationTimeOut = ProjectInvitationExpirationTime.value() * 1000;
        _allowUserToCreateProject = AllowUserToCreateProject.value();
        senderAddress = ProjectEmailSender.value();

        String namespace = "project.smtp";

        mailSender = new SMTPMailSender(configs, namespace);
        _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Project-ExpireInvitations"));

        return true;
    }

    @Override
    public boolean start() {
        _executor.scheduleWithFixedDelay(new ExpiredInvitationsCleanup(), _projectCleanupExpInvInterval, _projectCleanupExpInvInterval, TimeUnit.SECONDS);
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    private User validateUser(Long userId, Long accountId, Long domainId) {
        User user = null;
        if (userId != null) {
            user = userDao.findById(userId);
            if (user == null ) {
                throw new InvalidParameterValueException("Invalid user ID provided");
            }
            if (user.getAccountId() != accountId || _accountDao.findById(user.getAccountId()).getDomainId() != domainId) {
                throw new InvalidParameterValueException("User doesn't belong to the specified account or domain");
            }
        }
        return user;
    }

    private User validateUser(Long userId, Long domainId) {
        User user = null;
        if (userId != null) {
            user = userDao.findById(userId);
            if (user == null) {
                throw new InvalidParameterValueException("Invalid user ID provided");
            }
            if (_accountDao.findById(user.getAccountId()).getDomainId() != domainId) {
                throw new InvalidParameterValueException("User doesn't belong to the specified account or domain");
            }
        }
        return user;
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create = true)
    @DB
    public Project createProject(final String name, final String displayText, String accountName, final Long domainId, final Long userId, final Long accountId) throws ResourceAllocationException {
        Account caller = CallContext.current().getCallingAccount();
        Account owner = caller;

        //check if the user authorized to create the project
        if (_accountMgr.isNormalUser(caller.getId()) && !_allowUserToCreateProject) {
            throw new PermissionDeniedException("Regular user is not permitted to create a project");
        }

        //Verify request parameters
        if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
            throw new InvalidParameterValueException("Account name and domain id must be specified together");
        }

        if (userId != null && (accountId == null && domainId == null)) {
            throw new InvalidParameterValueException("Domain ID and account ID must be provided with User ID");
        }

        if (accountName != null) {
            owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
        }

        //don't allow 2 projects with the same name inside the same domain
        if (_projectDao.findByNameAndDomain(name, owner.getDomainId()) != null) {
            throw new InvalidParameterValueException("Project with name " + name + " already exists in domain id=" + owner.getDomainId());
        }

        User user = validateUser(userId, accountId, domainId);
        if (user != null) {
            owner = _accountDao.findById(user.getAccountId());
        }

        try (CheckedReservation projectReservation = new CheckedReservation(owner, ResourceType.project, null, null, 1L, reservationDao, _resourceLimitMgr)) {
            final Account ownerFinal = owner;
            User finalUser = user;
            Project project =  Transaction.execute(new TransactionCallback<Project>() {
                @Override
                public Project doInTransaction(TransactionStatus status) {

                    //Create an account associated with the project
                    StringBuilder acctNm = new StringBuilder("PrjAcct-");
                    acctNm.append(name).append("-").append(ownerFinal.getDomainId());

                    Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.Type.PROJECT, null, domainId, null, null, UUID.randomUUID().toString());

                    Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));

                    //assign owner to the project
                    assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin,
                            Optional.ofNullable(finalUser).map(User::getId).orElse(null),  null);

                if (project != null) {
                    CallContext.current().setEventDetails("Project ID: " + project.getUuid());
                    CallContext.current().putContextParameter(Project.class, project.getUuid());
                }

                    //Increment resource count
                    _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project);

                    return project;
                }
            });

            messageBus.publish(_name, ProjectManager.MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project);

            return project;
        }
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", async = true)
    @DB
    public Project enableProject(long projectId) {
        Account caller = CallContext.current().getCallingAccount();

        ProjectVO project = getProject(projectId);
        //verify input parameters
        if (project == null) {
            throw new InvalidParameterValueException("Unable to find project by id " + projectId);
        }

        CallContext.current().setProject(project);
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        //at this point enabling project doesn't require anything, so just update the state
        project.setState(State.Active);
        _projectDao.update(projectId, project);

        return project;
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
    public boolean deleteProject(long projectId, Boolean isCleanup) {
        CallContext ctx = CallContext.current();

        ProjectVO project = getProject(projectId);
        //verify input parameters
        if (project == null) {
            throw new InvalidParameterValueException("Unable to find project by id " + projectId);
        }

        CallContext.current().setProject(project);
        _accountMgr.checkAccess(ctx.getCallingAccount(), AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        if (isCleanup != null && isCleanup) {
            return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
        } else {
            List<VMTemplateVO> userTemplates = _templateDao.listByAccountId(project.getProjectAccountId());
            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByAccountId(project.getProjectAccountId());
            List<UserVmVO> vms = _userVmDao.listByAccountId(project.getProjectAccountId());
            List<VolumeVO> volumes = _volumeDao.findDetachedByAccount(project.getProjectAccountId());
            List<NetworkVO> networks = _networkDao.listByOwner(project.getProjectAccountId());
            List<? extends Vpc> vpcs = _vpcMgr.getVpcsForAccount(project.getProjectAccountId());
            List<? extends ControlledEntity> webhooks = listWebhooksForProject(project);

            Optional<String> message = Stream.of(userTemplates, vmSnapshots, vms, volumes, networks, vpcs, webhooks)
                    .filter(entity -> !entity.isEmpty())
                    .map(entity -> entity.size() + " " +  entity.get(0).getEntityType().getSimpleName() + " to clean up")
                    .findFirst();

            if (message.isEmpty()) {
                return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
            }

            CloudRuntimeException e = new CloudRuntimeException("Can't delete the project yet because it has " + message.get());
            e.addProxyObject(project.getUuid(), "projectId");
            throw e;
        }
    }

    @DB
    @Override
    public boolean deleteProject(Account caller, long callerUserId, final ProjectVO project) {
        //mark project as inactive first, so you can't add resources to it
        boolean updateResult = Transaction.execute(new TransactionCallback<Boolean>() {
            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                logger.debug("Marking project {} with state {} as a part of project delete...", project, State.Disabled);
        project.setState(State.Disabled);
        boolean updateResult = _projectDao.update(project.getId(), project);
        //owner can be already removed at this point, so adding the conditional check
        List<Long> projectOwners = getProjectOwners(project.getId());
        if (projectOwners != null) {
            for (Long projectOwner : projectOwners)
            _resourceLimitMgr.decrementResourceCount(projectOwner, ResourceType.project);
        }
                return updateResult;
            }
        });

        if (updateResult) {
            //pass system caller when clenaup projects account
            if (!cleanupProject(project, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM)) {
                logger.warn("Failed to cleanup project's ({}) resources, not removing the project yet", project);
                return false;
            } else {
                //check if any Tungsten-Fabric provider exists and delete the project from Tungsten-Fabric providers
                messageBus.publish(_name, ProjectManager.MESSAGE_DELETE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project);
                return _projectDao.remove(project.getId());
            }
        } else {
            logger.warn("Failed to mark the project {} with state {}", project, State.Disabled);
            return false;
        }
    }

    @DB
    private boolean cleanupProject(final Project project, AccountVO caller, Long callerUserId) {
        boolean result = true;
        //Delete project's account
        AccountVO account = _accountDao.findById(project.getProjectAccountId());
        logger.debug("Deleting projects {} internal account {} as a part of project cleanup...", project, account);

        result = result && _accountMgr.deleteAccount(account, callerUserId, caller);

        if (result) {
            //Unassign all users from the project
            result = Transaction.execute(new TransactionCallback<Boolean>() {
                @Override
                public Boolean doInTransaction(TransactionStatus status) {
                    boolean result = true;
            logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup...");
            List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId());
            for (ProjectAccount projectAccount : projectAccounts) {
                result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId());
            }

            logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
            _projectInvitationDao.cleanupInvitations(project.getId());
                    return result;
                }
            });
            if (result) {
                logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup...");
            }
        } else {
            logger.warn("Failed to cleanup project's internal account");
        }

        return result;
    }

    @Override
    public boolean unassignAccountFromProject(long projectId, long accountId) {
        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId);
        if (projectAccount == null) {
            logger.debug("Account id=" + accountId + " is not assigned to project id=" + projectId + " so no need to unassign");
            return true;
        }

        if (_projectAccountDao.remove(projectAccount.getId())) {
            return true;
        } else {
            logger.warn("Failed to unassign account id=" + accountId + " from the project id=" + projectId);
            return false;
        }
    }

    @Override
    public ProjectVO getProject(long projectId) {
        return _projectDao.findById(projectId);
    }

    @Override
    public long getInvitationTimeout() {
        return _invitationTimeOut;
    }

    @Override
    public ProjectAccount assignAccountToProject(Project project, long accountId, ProjectAccount.Role accountRole, Long userId, Long projectRoleId) {
        ProjectAccountVO projectAccountVO = new ProjectAccountVO(project, accountId, accountRole, userId, projectRoleId);
        return _projectAccountDao.persist(projectAccountVO);
    }

    public ProjectAccount assignUserToProject(Project project, long userId, long accountId, Role userRole, Long projectRoleId) {
       return assignAccountToProject(project, accountId, userRole, userId, projectRoleId);
    }

    @Override
    @DB
    public boolean deleteAccountFromProject(final long projectId, final Account account) {
        return Transaction.execute(new TransactionCallback<Boolean>() {
            @Override
            public Boolean doInTransaction(TransactionStatus status) {
        boolean success = true;

        //remove account
        ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
        success = _projectAccountDao.remove(projectAccount.getId());
        if (projectAccount.getAccountRole() == Role.Admin) {
            _resourceLimitMgr.decrementResourceCount(account.getId(), ResourceType.project);
        }

        //remove all invitations for account
        if (success) {
            logger.debug("Removed account {} from project {} , cleaning up old invitations for account/project...", account, projectId);
            ProjectInvitation invite = _projectInvitationDao.findByAccountIdProjectId(account.getId(), projectId);
            if (invite != null) {
                success = success && _projectInvitationDao.remove(invite.getId());
            }
        }

        return success;
    }
        });
    }

    @Override
    public Account getProjectOwner(long projectId) {
        ProjectAccount prAcct = _projectAccountDao.getProjectOwner(projectId);
        if (prAcct != null) {
            return _accountMgr.getAccount(prAcct.getAccountId());
        }

        return null;
    }

    @Override
    public List<Long> getProjectOwners(long projectId) {
        List<? extends ProjectAccount> projectAccounts = _projectAccountDao.getProjectOwners(projectId);
        if (projectAccounts != null || !projectAccounts.isEmpty()) {
            return projectAccounts.stream().map(acc -> _accountMgr.getAccount(acc.getAccountId()).getId()).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public ProjectVO findByProjectAccountId(long projectAccountId) {
        return _projectDao.findByProjectAccountId(projectAccountId);
    }

    @Override
    public ProjectVO findByProjectAccountIdIncludingRemoved(long projectAccountId) {
        return _projectDao.findByProjectAccountIdIncludingRemoved(projectAccountId);
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_USER_ADD, eventDescription = "adding user to project", async = true)
    public boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole) throws ResourceAllocationException {
        Account caller = CallContext.current().getCallingAccount();

        Project project = getProject(projectId);
        if (project == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
            ex.addProxyObject(String.valueOf(projectId), "projectId");
            throw ex;
        }

        if (project.getState() != State.Active) {
            InvalidParameterValueException ex =
                    new InvalidParameterValueException("Can't add user to the specified project id in state=" + project.getState() + " as it isn't currently active");
            ex.addProxyObject(project.getUuid(), "projectId");
            throw ex;
        }


        User user = userDao.getUserByName(username, project.getDomainId());
        if (user == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Invalid user ID provided");
            ex.addProxyObject(String.valueOf(username), "userId");
            throw ex;
        }

        CallContext.current().setProject(project);
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        Account userAccount = _accountDao.findById(user.getAccountId());
        if (_projectAccountDao.findByProjectIdAccountId(projectId, userAccount.getAccountId()) != null) {
            throw new InvalidParameterValueException("User belongs to account " + userAccount.getAccountId() + " which is already part of the project");
        }

        ProjectAccount projectAccountUser = _projectAccountDao.findByProjectIdUserId(projectId, user.getAccountId(), user.getId());
        if (projectAccountUser != null) {
            logger.info("User: {} is already added to the project: {}", user, project);
            return true;
        }

        if (projectRoleId != null && projectRoleId < 1L) {
            throw new InvalidParameterValueException("Invalid project role id provided");
        }

        ProjectRole role = null;
        if (projectRoleId != null) {
            role = projectRoleDao.findById(projectRoleId);
            if (role == null || !role.getProjectId().equals(projectId)) {
                throw new InvalidParameterValueException("Invalid project role ID for the given project");
            }
        }

        if (_invitationRequired) {
            return inviteUserToProject(project, user, email, projectRole, role);
        } else {
            if (username == null) {
                throw new InvalidParameterValueException("User information (ID) is required to add user to the project");
            }

            boolean shouldIncrementResourceCount = projectRole != null && Role.Admin == projectRole;
            try (CheckedReservation cr = new CheckedReservation(userAccount, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
                if (assignUserToProject(project, user.getId(), user.getAccountId(), projectRole,
                        Optional.ofNullable(role).map(ProjectRole::getId).orElse(null)) != null) {
                    if (shouldIncrementResourceCount) {
                        _resourceLimitMgr.incrementResourceCount(userAccount.getId(), ResourceType.project);
                    }
                    return true;
                } else {
                    logger.warn("Failed to add user to project: {}", project);
                    return false;
                }
            }
        }
    }

    /**
     * Transfers all project associations and project invitations from one user to another.
     *
     * @param oldUser the user whose project associations are being transferred
     * @param newUser the user to whom the project associations are being transferred
     * @throws ResourceAllocationException if there is an issue with allocating the required project resources to the new user
     */
    @Override
    public void moveProjectAssociationsToUser(User oldUser, User newUser) throws ResourceAllocationException {
        _projectInvitationDao.move(oldUser, newUser);

        List<ProjectAccountVO> projectAccounts = _projectAccountDao.listBy(null, oldUser.getAccountId(), oldUser.getId());
        if (projectAccounts.isEmpty()) {
            return;
        }

        Account oldAccount = _accountDao.findById(oldUser.getAccountId());
        Account newAccount = _accountDao.findById(newUser.getAccountId());
        long requiredProjectsAmount = oldAccount.getId() != newAccount.getId()
                ? projectAccounts.stream().filter(pa -> pa.getAccountRole() == ProjectAccount.Role.Admin).count()
                : 0L;

        try (CheckedReservation projectReservation = new CheckedReservation(newAccount, ResourceType.project, null, null, requiredProjectsAmount, reservationDao, _resourceLimitMgr)) {
            _projectAccountDao.move(oldUser, newUser);
            if (requiredProjectsAmount > 0) {
                _resourceLimitMgr.incrementResourceCount(newAccount.getId(), ResourceType.project, requiredProjectsAmount);
                _resourceLimitMgr.decrementResourceCount(oldAccount.getId(), ResourceType.project, requiredProjectsAmount);
            }
        }
    }

    @Override
    public Project findByNameAndDomainId(String name, long domainId) {
        return _projectDao.findByNameAndDomain(name, domainId);
    }

    @Override
    public boolean canAccessProjectAccount(Account caller, long accountId) {
        //ROOT admin always can access the project
        if (_accountMgr.isRootAdmin(caller.getId())) {
            return true;
        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
            Account owner = _accountMgr.getAccount(accountId);
            _accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
            return true;
        }
        User user = CallContext.current().getCallingUser();
        ProjectVO project = _projectDao.findByProjectAccountId(accountId);
        if (project != null) {
            ProjectAccount userProjectAccount = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId());
            if (userProjectAccount != null) {
                return _projectAccountDao.canUserAccessProjectAccount(user.getAccountId(), user.getId(), accountId);
            }
        }
        return _projectAccountDao.canAccessProjectAccount(caller.getId(), accountId);
    }

    @Override
    public boolean canModifyProjectAccount(Account caller, long accountId) {
        //ROOT admin always can access the project
        if (_accountMgr.isRootAdmin(caller.getId())) {
            return true;
        } else if (_accountMgr.isDomainAdmin(caller.getId())) {
            Account owner = _accountMgr.getAccount(accountId);
            _accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
            return true;
        }

        User user = CallContext.current().getCallingUser();
        Project project = CallContext.current().getProject();
        if (project != null) {
            ProjectAccountVO projectUser = _projectAccountDao.findByProjectIdUserId(project.getId(), caller.getAccountId(), user.getId());
            if (projectUser != null) {
                return _projectAccountDao.canUserModifyProject(project.getId(), caller.getAccountId(), user.getId());
            }
        }
        return _projectAccountDao.canModifyProjectAccount(caller.getId(), accountId);
    }

    private void updateProjectAccount(ProjectAccountVO futureOwner, Role newAccRole, Long accountId) throws ResourceAllocationException {
        Account account = _accountMgr.getAccount(accountId);
        boolean shouldIncrementResourceCount = Role.Admin == newAccRole;

        try (CheckedReservation checkedReservation = new CheckedReservation(account, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
            futureOwner.setAccountRole(newAccRole);
            _projectAccountDao.update(futureOwner.getId(), futureOwner);
            if (shouldIncrementResourceCount) {
                _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.project);
            } else {
                _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.project);
            }
        }
    }

    @Override
    @DB
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async = true)
    public Project updateProject(final long projectId, String name, final String displayText, final String newOwnerName) throws ResourceAllocationException {
        Account caller = CallContext.current().getCallingAccount();

        //check that the project exists
        final ProjectVO project = getProject(projectId);

        if (project == null) {
            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
        }

        //verify permissions
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
                updateProjectNameAndDisplayText(project, name, displayText);

                if (newOwnerName != null) {
                    //check that the new owner exists
                    Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
                    if (futureOwnerAccount == null) {
                        throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
                    }
                    Account currentOwnerAccount = getProjectOwner(projectId);
                    if (currentOwnerAccount == null) {
                        logger.error("Unable to find the current owner for the project {}", project);
                        throw new InvalidParameterValueException(String.format("Unable to find the current owner for the project %s", project));
                    }
                    if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
                        ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
                        if (futureOwner == null) {
                            throw new InvalidParameterValueException("Account " + newOwnerName +
                                    " doesn't belong to the project. Add it to the project first and then change the project's ownership");
                        }

                        try (CheckedReservation checkedReservation = new CheckedReservation(futureOwnerAccount, ResourceType.project, null, null, 1L, reservationDao, _resourceLimitMgr)) {
                            //unset the role for the old owner
                            ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
                            currentOwner.setAccountRole(Role.Regular);
                            _projectAccountDao.update(currentOwner.getId(), currentOwner);
                            _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);

                            //set new owner
                            futureOwner.setAccountRole(Role.Admin);
                            _projectAccountDao.update(futureOwner.getId(), futureOwner);
                            _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
                        }
                    } else {
                        logger.trace("Future owner {}is already the owner of the project {}", newOwnerName, project);
                    }
                }
            }
        });

        return _projectDao.findById(projectId);

    }

    @Override
    @DB
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async = true)
    public Project updateProject(final long projectId, String name, final String displayText, final String newOwnerName, Long userId,
                                 Role newRole) throws ResourceAllocationException {
        Account caller = CallContext.current().getCallingAccount();

        //check that the project exists
        final ProjectVO project = getProject(projectId);

        if (project == null) {
            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
        }

        CallContext.current().setProject(project);
        //verify permissions
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        List<? extends  ProjectAccount> projectOwners = _projectAccountDao.getProjectOwners(projectId);

        Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
                updateProjectNameAndDisplayText(project, name, displayText);

                if (newOwnerName != null) {
                    //check that the new owner exists
                    Account updatedAcc = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
                    if (updatedAcc == null) {
                        throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
                    }
                    ProjectAccountVO newProjectAcc = _projectAccountDao.findByProjectIdAccountId(projectId, updatedAcc.getAccountId());
                    if (newProjectAcc == null) {
                        throw new InvalidParameterValueException("Account " + newOwnerName +
                                " doesn't belong to the project. Add it to the project first and then change the project's ownership");
                    }

                    if (isTheOnlyProjectOwner(projectId, newProjectAcc, caller) && newRole != Role.Admin) {
                        throw new InvalidParameterValueException("Cannot demote the only admin of the project");
                    }
                    updateProjectAccount(newProjectAcc, newRole, updatedAcc.getId());
                } else if (userId != null) {
                    User user = validateUser(userId, project.getDomainId());
                    if (user == null) {
                        throw new InvalidParameterValueException("Unable to find user= " + user.getUsername() + " in domain id = " + project.getDomainId());
                    }
                    ProjectAccountVO newProjectUser = _projectAccountDao.findByProjectIdUserId(projectId, user.getAccountId(), userId);
                    if (newProjectUser == null) {
                        throw new InvalidParameterValueException(String.format("User %s doesn't belong to the project. Add it to the project first and then change the project's ownership", user));
                    }

                    if (projectOwners.size() == 1 && newProjectUser.getUserId().equals(projectOwners.get(0).getUserId())
                            && newRole != Role.Admin ) {
                        throw new InvalidParameterValueException("Cannot demote the only admin of the project");
                    }

                    updateProjectAccount(newProjectUser, newRole, user.getAccountId());

                }
            }
        });
        return _projectDao.findById(projectId);
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_ADD, eventDescription = "adding account to project", async = true)
    public boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType) throws ResourceAllocationException {
        Account caller = CallContext.current().getCallingAccount();

        //check that the project exists
        Project project = getProject(projectId);

        if (project == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
            ex.addProxyObject(String.valueOf(projectId), "projectId");
            throw ex;
        }

        //User can be added to Active project only
        if (project.getState() != Project.State.Active) {
            InvalidParameterValueException ex =
                new InvalidParameterValueException("Can't add account to the specified project id in state=" + project.getState() + " as it's no longer active");
            ex.addProxyObject(project.getUuid(), "projectId");
            throw ex;
        }

        //check that account-to-add exists
        Account account = null;
        if (accountName != null) {
            account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
            if (account == null) {
                InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in specified domain id");
                DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
                String domainUuid = String.valueOf(project.getDomainId());
                if (domain != null) {
                    domainUuid = domain.getUuid();
                }
                ex.addProxyObject(domainUuid, "domainId");
                throw ex;
            }

            CallContext.current().setProject(project);
            //verify permissions - only project owner can assign
            _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

            //Check if the account already added to the project
            ProjectAccount projectAccount =  _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
            if (projectAccount != null) {
                logger.debug("Account {} already added to the project {}", accountName, project);
                return true;
            }
        }

        if (projectRoleId != null && projectRoleId < 1L) {
            throw new InvalidParameterValueException("Invalid project role id provided");
        }

        ProjectRole projectRole = null;
        if (projectRoleId != null) {
            projectRole = projectRoleDao.findById(projectRoleId);
            if (projectRole == null || projectRole.getProjectId() != projectId) {
                throw new InvalidParameterValueException("Invalid project role ID for the given project");
            }
        }

        if (_invitationRequired) {
            return inviteAccountToProject(project, account, email, projectRoleType, projectRole);
        } else {
            if (account == null) {
                throw new InvalidParameterValueException("Account information is required for assigning account to the project");
            }

            boolean shouldIncrementResourceCount = projectRoleType != null && Role.Admin == projectRoleType;
            try (CheckedReservation cr = new CheckedReservation(account, ResourceType.project, shouldIncrementResourceCount ? 1L : 0L, reservationDao, _resourceLimitMgr)) {
                if (assignAccountToProject(project, account.getId(), projectRoleType, null,
                        Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
                    if (shouldIncrementResourceCount) {
                        _resourceLimitMgr.incrementResourceCount(account.getId(), ResourceType.project);
                    }
                    return true;
                } else {
                    logger.warn("Failed to add account {} to project {}", accountName, project);
                    return false;
                }
            }
        }
    }

    private boolean inviteAccountToProject(Project project, Account account, String email, Role role,ProjectRole projectRole) {
        if (account != null) {
            if (createAccountInvitation(project, account.getId(), null, role,
                    Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
                return true;
            } else {
                logger.warn("Failed to generate invitation for account {} to project {}", account, project);
                return false;
            }
        }

        if (email != null) {
            //generate the token
            String token = generateToken(10);
            if (generateTokenBasedInvitation(project, null, email, token, role,
                    Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
                return true;
            } else {
                logger.warn("Failed to generate invitation for email {} to project {}", email, project);
                return false;
            }
        }

        return false;
    }

    private boolean inviteUserToProject(Project project, User user, String email, Role role, ProjectRole projectRole) {
        if (email == null) {
            if (createAccountInvitation(project, user.getAccountId(), user.getId(), role,
                    Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
                return true;
            } else {
                logger.warn("Failed to generate invitation for account {} to project {}", user, project);
                return false;
            }
        } else {
            //generate the token
            String token = generateToken(10);
            if (generateTokenBasedInvitation(project, user.getId(), email, token, role,
                    Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
                return true;
            } else {
                logger.warn("Failed to generate invitation for email {} to project {}", email, project);
                return false;
            }
        }
    }

    private boolean isTheOnlyProjectOwner(Long projectId, ProjectAccount projectAccount, Account caller) {
        List<? extends  ProjectAccount> projectOwners = _projectAccountDao.getProjectOwners(projectId);
        if ((projectOwners.size() == 1 && projectOwners.get(0).getAccountId() == projectAccount.getAccountId()
                && projectAccount.getAccountRole() == Role.Admin )) {
            return true;
        }
        return false;
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_REMOVE, eventDescription = "removing account from project", async = true)
    public boolean deleteAccountFromProject(long projectId, String accountName) {
        Account caller = CallContext.current().getCallingAccount();

        //check that the project exists
        Project project = getProject(projectId);

        if (project == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
            ex.addProxyObject(String.valueOf(projectId), "projectId");
            throw ex;
        }

        //check that account-to-remove exists
        Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
        if (account == null) {
            InvalidParameterValueException ex =
                new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId());
            DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
            String domainUuid = String.valueOf(project.getDomainId());
            if (domain != null) {
                domainUuid = domain.getUuid();
            }
            ex.addProxyObject(domainUuid, "domainId");
            throw ex;
        }

        CallContext.current().setProject(project);
        //verify permissions
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        //Check if the account exists in the project
        ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
        if (projectAccount == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Account " + accountName + " is not assigned to the project with specified id");
            // Use the projectVO object and not the projectAccount object to inject the projectId.
            ex.addProxyObject(project.getUuid(), "projectId");
            throw ex;
        }

        //can't remove the owner of the project
        if (isTheOnlyProjectOwner(projectId, projectAccount, caller)) {
            InvalidParameterValueException ex =
                new InvalidParameterValueException("Unable to delete account " + accountName +
                    " from the project with specified id as the account is the owner of the project");
            ex.addProxyObject(project.getUuid(), "projectId");
            throw ex;
        }

        return deleteAccountFromProject(projectId, account);
    }

    @Override
    public boolean deleteUserFromProject(long projectId, long userId) {
        Account caller = CallContext.current().getCallingAccount();
        //check that the project exists
        Project project = getProject(projectId);

        if (project == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
            ex.addProxyObject(String.valueOf(projectId), "projectId");
            throw ex;
        }

        User user = userDao.findById(userId);
        if (user == null) {
            throw new InvalidParameterValueException("Invalid userId provided");
        }
        Account userAcc = _accountDao.findActiveAccountById(user.getAccountId(), project.getDomainId());
        if (userAcc == null) {
            InvalidParameterValueException ex =
                    new InvalidParameterValueException("Unable to find user "+ user.getUsername() + " in domain id=" + project.getDomainId());
            DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
            String domainUuid = String.valueOf(project.getDomainId());
            if (domain != null) {
                domainUuid = domain.getUuid();
            }
            ex.addProxyObject(domainUuid, "domainId");
            throw ex;
        }

        CallContext.current().setProject(project);
        //verify permissions
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        boolean success = cleanupProjectsForUser(project, user);
        if (!success) {
            InvalidParameterValueException ex = new InvalidParameterValueException("User " + user.getUsername() + " is not assigned to the project with specified id");
            ex.addProxyObject(project.getUuid(), "projectId");
            throw ex;
        }
        return true;
    }

    /**
     * Cleans up project associations and invitations for a specified user in a given project.
     *
     * @param project the project from which the user is being cleaned up; if null, cleanup applies to all projects associated with the user
     * @param user the user whose project associations and invitations are being cleaned up
     * @return true if any project accounts associated with the user were removed, false otherwise
     */
    @Override
    public boolean cleanupProjectsForUser(Project project, User user) {
        return Transaction.execute((TransactionCallback<Boolean>) status -> {
            Long projectId = project != null ? project.getId() : null;
            long userId = user.getId();
            long accountId = user.getAccountId();

            _projectInvitationDao.removeBy(projectId, accountId, userId);

            List<ProjectAccountVO> projectAccounts = _projectAccountDao.listBy(projectId, accountId, userId);
            for (ProjectAccountVO projectAccount : projectAccounts) {
                _projectAccountDao.remove(projectAccount.getId());
                if (projectAccount.getAccountRole() == Role.Admin) {
                    _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.project);
                }
                logger.debug("Removed user [{}] from project [{}].", user, projectAccount.getProjectId());
            }

            return !projectAccounts.isEmpty();
        });
    }

    public ProjectInvitation createAccountInvitation(Project project, Long accountId, Long userId, Role role, Long projectRoleId) {
        if (activeInviteExists(project, accountId, userId, null)) {
            throw new InvalidParameterValueException("There is already a pending invitation for account id=" + accountId + " to the project id=" + project);
        }

        ProjectInvitationVO invitationVO = new ProjectInvitationVO(project.getId(), accountId, project.getDomainId(), null, null);
        if (userId != null) {
            invitationVO.setForUserId(userId);
        }
        if (role != null) {
            invitationVO.setAccountRole(role);
        }
        if (projectRoleId != null) {
            invitationVO.setProjectRoleId(projectRoleId);
        }
        return  _projectInvitationDao.persist(invitationVO);
    }

    @DB
    public boolean activeInviteExists(final Project project, final Long accountId, Long userId, final String email) {
        return Transaction.execute(new TransactionCallback<Boolean>() {
            @Override
            public Boolean doInTransaction(TransactionStatus status) {
        //verify if the invitation was already generated
        ProjectInvitationVO invite = null;
        if (accountId != null) {
            invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
        } else if (userId != null) {
            invite = _projectInvitationDao.findByUserIdProjectId(userId, accountId, project.getId());
        } else if (email != null) {
            invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
        }

        if (invite != null) {
            if (invite.getState() == ProjectInvitation.State.Completed ||
                    (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) {
                return true;
            } else {
                if (invite.getState() == ProjectInvitation.State.Pending) {
                    expireInvitation(invite);
                }
                //remove the expired/declined invitation
                if (accountId != null) {
                    logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
                } else if (userId != null) {
                    logger.debug("Removing invitation in state " + invite.getState() + " for user id=" + userId + " to project " + project);
                } else if (email != null) {
                    logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
                }

                _projectInvitationDao.expunge(invite.getId());
            }
        }

        return false;
    }
        });
    }

    public ProjectInvitation generateTokenBasedInvitation(Project project, Long userId, String email, String token, Role role, Long projectRoleId) {
        //verify if the invitation was already generated
        if (activeInviteExists(project, null, null, email)) {
            throw new InvalidParameterValueException(String.format("There is already a pending invitation for email %s to the project %s", email, project));
        }

        ProjectInvitationVO projectInvitationVO = new ProjectInvitationVO(project.getId(), null, project.getDomainId(), email, token);
        if (userId != null) {
            projectInvitationVO.setForUserId(userId);
        }
        if (role != null) {
            projectInvitationVO.setAccountRole(role);
        }
        if (projectRoleId != null) {
            projectInvitationVO.setProjectRoleId(projectRoleId);
        }

        ProjectInvitation projectInvitation = _projectInvitationDao.persist(projectInvitationVO);
        try {
            sendInvite(token, email, project.getId());
        } catch (Exception ex) {
            logger.warn("Failed to send project {} invitation to the email {}; removing the invitation record from the db", project, email, ex);
            _projectInvitationDao.remove(projectInvitation.getId());
            return null;
        }

        return projectInvitation;
    }

    protected void sendInvite(String token, String email, long projectId) throws MessagingException, UnsupportedEncodingException {
        String subject = String.format("You are invited to join the cloud stack project id=[%s].", projectId);
        String content = String.format("You've been invited to join the CloudStack project id=[%s]. Please use token [%s] to complete registration", projectId, token);

        SMTPMailProperties mailProperties = new SMTPMailProperties();

        mailProperties.setSender(new MailAddress(senderAddress));
        mailProperties.setSubject(subject);
        mailProperties.setContent(content);
        mailProperties.setContentType("text/plain");

        Set<MailAddress> addresses = new HashSet<>();

        addresses.add(new MailAddress(email));

        mailProperties.setRecipients(addresses);

        mailSender.sendMail(mailProperties);

    }

    private boolean expireInvitation(ProjectInvitationVO invite) {
        logger.debug("Expiring invitation {}", invite);
        invite.setState(ProjectInvitation.State.Expired);
        return _projectInvitationDao.update(invite.getId(), invite);
    }

    @Override
    @DB
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async = true)
    public boolean updateInvitation(final long projectId, String accountName, Long userId, String token, final boolean accept) {
        Account caller = CallContext.current().getCallingAccount();
        Long accountId = null;
        User user = null;
        boolean result = true;

        //check that the project exists
        final Project project = getProject(projectId);

        if (project == null) {
            throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
        }
        CallContext.current().setProject(project);
        if (accountName != null) {
            //check that account-to-remove exists
            Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
            if (account == null) {
                throw new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId());
            }

            //verify permissions
            _accountMgr.checkAccess(caller, null, true, account);
            accountId = account.getId();
        } else if (userId != null) {
            user = userDao.findById(userId);
            if (user == null) {
                throw new InvalidParameterValueException("Invalid user ID provided. Please provide a valid user ID or " +
                        "account name whose invitation is to be updated");
            }
            Account userAccount = _accountDao.findById(user.getAccountId());
            if (userAccount.getDomainId() != project.getDomainId()) {
                throw new InvalidParameterValueException("Unable to find user =" + userId + " in domain id=" + project.getDomainId());
            }
        } else {
            accountId = caller.getId();
            user = CallContext.current().getCallingUser();
        }

        //check that invitation exists
        ProjectInvitationVO invite = null;
        if (token == null) {
            if (accountName != null) {
                invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId, ProjectInvitation.State.Pending);
            } else {
                invite = _projectInvitationDao.findByUserIdProjectId(user.getId(), user.getAccountId(), projectId, ProjectInvitation.State.Pending);
            }
        } else {
            invite = _projectInvitationDao.findPendingByTokenAndProjectId(token, projectId, ProjectInvitation.State.Pending);
        }

        if (invite != null) {
            if (!_projectInvitationDao.isActive(invite.getId(), _invitationTimeOut) && accept) {
                expireInvitation(invite);
                throw new InvalidParameterValueException(String.format("Invitation is expired for account id=%s to the project %s", accountName, project));
            } else {
                final ProjectInvitationVO inviteFinal = invite;
                final Long accountIdFinal = invite.getAccountId() != -1 ? invite.getAccountId() : accountId;
                final String accountNameFinal = accountName;
                final User finalUser = getFinalUser(user, invite);
                result = Transaction.execute(new TransactionCallback<Boolean>() {
                    @Override
                    public Boolean doInTransaction(TransactionStatus status) {
                        boolean result = true;

                        ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;

                        //update invitation
                        logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
                        inviteFinal.setState(newState);
                        result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);

                        if (result && accept) {
                            //check if account already exists for the project (was added before invitation got accepted)
                            if (inviteFinal.getForUserId() == -1) {
                                ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
                                if (projectAccount != null) {
                                    logger.debug("Account {} already added to the project {}", accountNameFinal, project);
                                } else {
                                    assignAccountToProject(project, accountIdFinal, inviteFinal.getAccountRole(), null, inviteFinal.getProjectRoleId());
                                }
                            } else {
                                ProjectAccount projectAccount = _projectAccountDao.findByProjectIdUserId(projectId, finalUser.getAccountId(), finalUser.getId());
                                if (projectAccount != null) {
                                    logger.debug("User {} has already been added to the project {}", finalUser, project);
                                } else {
                                    assignUserToProject(project, inviteFinal.getForUserId(), finalUser.getAccountId(), inviteFinal.getAccountRole(), inviteFinal.getProjectRoleId());
                                }
                            }
                        } else {
                            logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
                        }
                        return result;
                    }
                });
            }
        } else {
            throw new InvalidParameterValueException(String.format("Unable to find invitation for account name=%s to the project=%s", accountName, project));
        }

        return result;
    }

    private User getFinalUser(User user, ProjectInvitationVO invite) {
        User returnedUser = user;
        if (invite.getForUserId() != -1 && invite.getForUserId() != user.getId()) {
            returnedUser = userDao.getUser(invite.getForUserId());
        }
        return returnedUser;
    }

    @Override
    public List<Long> listPermittedProjectAccounts(long accountId) {
        return _projectAccountDao.listPermittedAccountIds(accountId);
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project", async = true)
    @DB
    public Project activateProject(final long projectId) {
        Account caller = CallContext.current().getCallingAccount();

        //check that the project exists
        final ProjectVO project = getProject(projectId);

        if (project == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
            ex.addProxyObject(String.valueOf(projectId), "projectId");
            throw ex;
        }

        CallContext.current().setProject(project);
        //verify permissions
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        //allow project activation only when it's in Suspended state
        Project.State currentState = project.getState();

        if (currentState == State.Active) {
            logger.debug("The project {} is already active, no need to activate it again", project);
            return project;
        }

        if (currentState != State.Suspended) {
            throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state");
        }

        Transaction.execute(new TransactionCallbackNoReturn() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {
        project.setState(Project.State.Active);
        _projectDao.update(projectId, project);

        _accountMgr.enableAccount(project.getProjectAccountId());
            }
        });

        return _projectDao.findById(projectId);
    }

    @Override
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_SUSPEND, eventDescription = "suspending project", async = true)
    public Project suspendProject(long projectId) throws ConcurrentOperationException, ResourceUnavailableException {
        Account caller = CallContext.current().getCallingAccount();

        ProjectVO project = getProject(projectId);
        //verify input parameters
        if (project == null) {
            InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
            ex.addProxyObject(String.valueOf(projectId), "projectId");
            throw ex;
        }

        CallContext.current().setProject(project);
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        if (suspendProject(project)) {
            logger.debug("Successfully suspended project {}", project);
            return _projectDao.findById(projectId);
        } else {
            CloudRuntimeException ex = new CloudRuntimeException("Failed to suspend project with specified id");
            ex.addProxyObject(project.getUuid(), "projectId");
            throw ex;
        }

    }

    private boolean suspendProject(ProjectVO project) throws ConcurrentOperationException, ResourceUnavailableException {

        logger.debug("Marking project " + project + " with state " + State.Suspended + " as a part of project suspend...");
        project.setState(State.Suspended);
        boolean updateResult = _projectDao.update(project.getId(), project);

        if (updateResult) {
            long projectAccountId = project.getProjectAccountId();
            if (!_accountMgr.disableAccount(projectAccountId)) {
                logger.warn("Failed to suspend all project's " + project + " resources; the resources will be suspended later by background thread");
            }
        } else {
            throw new CloudRuntimeException("Failed to mark the project " + project + " with state " + State.Suspended);
        }
        return true;
    }

    public static String generateToken(int length) {
        String charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int pos = secureRandom.nextInt(charset.length());
            sb.append(charset.charAt(pos));
        }
        return sb.toString();
    }

    @Override
    @DB
    @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_REMOVE, eventDescription = "removing project invitation", async = true)
    public boolean deleteProjectInvitation(long id) {
        Account caller = CallContext.current().getCallingAccount();

        ProjectInvitation invitation = _projectInvitationDao.findById(id);
        if (invitation == null) {
            throw new InvalidParameterValueException("Unable to find project invitation by id " + id);
        }

        //check that the project exists
        Project project = getProject(invitation.getProjectId());

        CallContext.current().setProject(project);
        //check permissions - only project owner can remove the invitations
        _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

        if (_projectInvitationDao.remove(id)) {
            logger.debug("Project Invitation {} is removed", invitation);
            return true;
        } else {
            logger.debug("Failed to remove project invitation {}", invitation);
            return false;
        }
    }

    public class ExpiredInvitationsCleanup extends ManagedContextRunnable {
        @Override
        protected void runInContext() {
            try {
                TimeZone.getDefault();
                List<ProjectInvitationVO> invitationsToExpire = _projectInvitationDao.listInvitationsToExpire(_invitationTimeOut);
                if (!invitationsToExpire.isEmpty()) {
                    logger.debug("Found " + invitationsToExpire.size() + " projects to expire");
                    for (ProjectInvitationVO invitationToExpire : invitationsToExpire) {
                        invitationToExpire.setState(ProjectInvitation.State.Expired);
                        _projectInvitationDao.update(invitationToExpire.getId(), invitationToExpire);
                        logger.trace("Expired project invitation {}", invitationToExpire);
                    }
                }
            } catch (Exception ex) {
                logger.warn("Exception while running expired invitations cleanup", ex);
            }
        }
    }

    @Override
    public boolean projectInviteRequired() {
        return _invitationRequired;
    }

    @Override
    public boolean allowUserToCreateProject() {
        return _allowUserToCreateProject;
    }

    @Override
    public String getConfigComponentName() {
        return ProjectManager.class.getSimpleName();
    }

    @Override
    public ConfigKey<?>[] getConfigKeys() {
        return new ConfigKey<?>[] {ProjectSmtpEnabledSecurityProtocols, ProjectSmtpUseStartTLS, ProjectSmtpUseAuth,
                ProjectInviteRequired, ProjectInvitationExpirationTime, AllowUserToCreateProject, ProjectEmailSender,
                ProjectSMTPHost, ProjectSMTPPort, ProjectSMTPUsername, ProjectSMTPPassword};
    }

    protected void updateProjectNameAndDisplayText(final ProjectVO project, String name, String displayText) {
        if (name == null && displayText == null){
            return;
        }
        if (name != null) {
            project.setName(name);
        }
        if (displayText != null) {
            project.setDisplayText(displayText);
        }
        _projectDao.update(project.getId(), project);
    }
}
