/*
 * Copyright (C) 2005-2013 Alfresco Software Limited.
 *
 * This file is part of Alfresco
 *
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see .
 */
package org.alfresco.repo.tenant;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.domain.tenant.TenantAdminDAO;
import org.alfresco.repo.domain.tenant.TenantEntity;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.springframework.extensions.surf.util.I18NUtil;
/*
 * MT Service implementation
 *
 * Adapts names to be tenant specific or vice-versa, if MT is enabled (otherwise NOOP).
 *
 * author janv
 * since 3.0
 */
public class MultiTServiceImpl implements TenantService
{
    private TenantAdminDAO tenantAdminDAO;
    
    public void setTenantAdminDAO(TenantAdminDAO tenantAdminDAO)
    {
        this.tenantAdminDAO = tenantAdminDAO;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.cmr.repository.NodeRef)
     */
    public NodeRef getName(NodeRef nodeRef)
    {
        if (nodeRef == null) { return null; }
        
        return new NodeRef(nodeRef.getStoreRef().getProtocol(), getName(nodeRef.getStoreRef().getIdentifier()), nodeRef.getId());
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef)
     */
    public NodeRef getName(NodeRef inNodeRef, NodeRef nodeRef)
    {
        if (inNodeRef == null || nodeRef == null) { return null; }
        
        int idx = inNodeRef.getStoreRef().getIdentifier().lastIndexOf(SEPARATOR);
        if (idx != -1)
        {   
            String tenantDomain = inNodeRef.getStoreRef().getIdentifier().substring(1, idx);
            return new NodeRef(nodeRef.getStoreRef().getProtocol(), getName(nodeRef.getStoreRef().getIdentifier(), tenantDomain), nodeRef.getId());            
        }
        
        return nodeRef;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.cmr.repository.StoreRef)
     */
    public StoreRef getName(StoreRef storeRef)
    {
        if (storeRef == null) { return null; }
        
        return new StoreRef(storeRef.getProtocol(), getName(storeRef.getIdentifier()));
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.cmr.repository.ChildAssociationRef)
     */
    public ChildAssociationRef getName(ChildAssociationRef childAssocRef)
    {
        if (childAssocRef == null) { return null; }
        
        return new ChildAssociationRef(
                childAssocRef.getTypeQName(),
                getName(childAssocRef.getParentRef()),
                childAssocRef.getQName(),
                getName(childAssocRef.getChildRef()),
                childAssocRef.isPrimary(), 
                childAssocRef.getNthSibling());
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.cmr.repository.AssociationRef)
     */
    public AssociationRef getName(AssociationRef assocRef)
    {
        if (assocRef == null) { return null; }
        
        return new AssociationRef(assocRef.getId(),
                getName(assocRef.getSourceRef()),
                assocRef.getTypeQName(),
                getName(assocRef.getTargetRef()));
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(java.lang.String, org.alfresco.service.cmr.repository.StoreRef)
     */
    public StoreRef getName(String username, StoreRef storeRef)
    {
        if (storeRef == null) { return null; }
        
        if ((username != null) && (AuthenticationUtil.isMtEnabled()))
        {
            int idx = username.lastIndexOf(SEPARATOR);
            if ((idx > 0) && (idx < (username.length()-1)))
            {
                String tenantDomain = username.substring(idx+1);
                return new StoreRef(storeRef.getProtocol(), getName(storeRef.getIdentifier(), tenantDomain));
            }
        }
        
        return storeRef;
    }
    
    protected StoreRef getName(StoreRef storeRef, String tenantDomain, boolean checkTenantEnabled)
    {
        if (storeRef == null) { return null; }
        if (tenantDomain != null) 
        {
            storeRef = new StoreRef(storeRef.getProtocol(), getName(storeRef.getIdentifier(), tenantDomain, checkTenantEnabled));
        }
        
        return storeRef;
    }
    
    protected String getName(String name, String tenantDomain)
    {
        return getName(name, tenantDomain, true);
    }
    
    protected String getName(String name, String tenantDomain, boolean checkTenantEnabled)
    {
        ParameterCheck.mandatory("tenantDomain", tenantDomain);
        
        if (name == null)
        {
            return null;
        }
        
        if (checkTenantEnabled)
        {
            checkTenantEnabled(tenantDomain);
        }
        
        int idx1 = name.indexOf(SEPARATOR);
        if (idx1 != 0)
        {
            // no domain, so add it as a prefix (between two domain separators)
            name = SEPARATOR + tenantDomain + SEPARATOR + name;
        }
        else
        {
            int idx2 = name.indexOf(SEPARATOR, 1);
            String nameDomain = name.substring(1, idx2);
            if (! tenantDomain.equalsIgnoreCase(nameDomain))
            {
                throw new AlfrescoRuntimeException("domain mismatch: expected = " + tenantDomain + ", actual = " + nameDomain);
            }
        }
        
        return name;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.namespace.QName)
     */
    public QName getName(QName name)
    {
        String tenantDomain = getCurrentUserDomain();
        
        if (! tenantDomain.equals(DEFAULT_DOMAIN))
        {
            checkTenantEnabled(tenantDomain);
            name = getName(name, tenantDomain);
        }
        
        return name;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
     */
    public QName getName(NodeRef inNodeRef, QName name)
    {
        ParameterCheck.mandatory("InNodeRef", inNodeRef);
        
        int idx = inNodeRef.getStoreRef().getIdentifier().lastIndexOf(SEPARATOR);
        if (idx != -1)
        {
            String tenantDomain = inNodeRef.getStoreRef().getIdentifier().substring(1, idx);
            checkTenantEnabled(tenantDomain);
            return getName(name, tenantDomain);
        }
        
        return name;
    }
    
    private QName getName(QName name, String tenantDomain)
    {
        if (name == null)
        {
            return null;
        }
        
        String namespace = name.getNamespaceURI();
        int idx1 = namespace.indexOf(SEPARATOR);
        if (idx1 == -1)
        {
            // no domain, so add it as a prefix (between two domain separators)
            namespace = SEPARATOR + tenantDomain + SEPARATOR + namespace;
            name = QName.createQName(namespace, name.getLocalName());
        }
        else
        {
            int idx2 = namespace.indexOf(SEPARATOR, 1);
            String nameDomain = namespace.substring(1, idx2);
            if (! tenantDomain.equalsIgnoreCase(nameDomain))
            {
                throw new AlfrescoRuntimeException("domain mismatch: expected = " + tenantDomain + ", actual = " + nameDomain);
            }
        }
        
        return name;
    }
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getName(java.lang.String)
     */
    public String getName(String name)
    {
        if (name == null)
        {
            return null;
        }
        
        String tenantDomain = getCurrentUserDomain();
        
        if (! tenantDomain.equals(DEFAULT_DOMAIN))
        {
            int idx1 = name.indexOf(SEPARATOR);
            if (idx1 != 0)
            {
                // no tenant domain prefix, so add it
                name = SEPARATOR + tenantDomain + SEPARATOR + name;
            }
            else
            {
                int idx2 = name.indexOf(SEPARATOR, 1);
                String nameDomain = name.substring(1, idx2);
                if (! tenantDomain.equalsIgnoreCase(nameDomain))
                {
                    throw new AlfrescoRuntimeException("domain mismatch: expected = " + tenantDomain + ", actual = " + nameDomain);
                }
            }
        }
        
        return name;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.namespace.QName, boolean)
     */
    public QName getBaseName(QName name, boolean forceForNonTenant)
    {  
        String baseNamespaceURI = getBaseName(name.getNamespaceURI(), forceForNonTenant);
        return QName.createQName(baseNamespaceURI, name.getLocalName());
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.NodeRef)
     */
    public NodeRef getBaseName(NodeRef nodeRef)
    {
        return getBaseName(nodeRef, false);
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.NodeRef, boolean)
     */
    public NodeRef getBaseName(NodeRef nodeRef, boolean forceForNonTenant)
    {
        if (nodeRef == null) { return null; }
        return new NodeRef(nodeRef.getStoreRef().getProtocol(), getBaseName(nodeRef.getStoreRef().getIdentifier(), forceForNonTenant), nodeRef.getId());
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.StoreRef)
     */
    public StoreRef getBaseName(StoreRef storeRef)
    {         
        if (storeRef == null) { return null; }
        
        return new StoreRef(storeRef.getProtocol(), getBaseName(storeRef.getIdentifier()));
    } 
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.ChildAssociationRef)
     */
    public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef)
    {
        return getBaseName(childAssocRef, false);
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean)
     */
    public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef, boolean forceForNonTenant)
    {
        if (childAssocRef == null) { return null; }
        
        return new ChildAssociationRef(
                childAssocRef.getTypeQName(),
                getBaseName(childAssocRef.getParentRef(), forceForNonTenant),
                childAssocRef.getQName(),
                getBaseName(childAssocRef.getChildRef(), forceForNonTenant),
                childAssocRef.isPrimary(), 
                childAssocRef.getNthSibling());
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(org.alfresco.service.cmr.repository.AssociationRef)
     */
    public AssociationRef getBaseName(AssociationRef assocRef)
    {
        if (assocRef == null) { return null; }
        
        return new AssociationRef(assocRef.getId(),
                getBaseName(assocRef.getSourceRef()),
                assocRef.getTypeQName(),
                getBaseName(assocRef.getTargetRef()));
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(java.lang.String)
     */
    public String getBaseName(String name)
    {  
        // get base name, but don't force for non-tenant user (e.g. super admin)
        return getBaseName(name, false);       
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseName(java.lang.String, boolean)
     */
    public String getBaseName(String name, boolean forceForNonTenant)
    {
        if (name == null)
        {
            return null;
        }
        
        String tenantDomain = getCurrentUserDomain();
        
        int idx1 = name.indexOf(SEPARATOR);
        if (idx1 == 0)
        {
            int idx2 = name.indexOf(SEPARATOR, 1);
            String nameDomain = name.substring(1, idx2);
            
            if ((! tenantDomain.equals(DEFAULT_DOMAIN)) && (! tenantDomain.equals(nameDomain)))
            {
                throw new AlfrescoRuntimeException("domain mismatch: expected = " + tenantDomain + ", actual = " + nameDomain);
            }
            
            if ((! tenantDomain.equals(DEFAULT_DOMAIN)) || (forceForNonTenant))
            {
                // remove tenant domain
                name = name.substring(idx2+1);
            }
        }
        
        return name;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getBaseNameUser(java.lang.String)
     */
    public String getBaseNameUser(String name)
    {
        // can be null (e.g. for System user / during app ctx init)
        if (name != null) 
        {
            int idx = name.lastIndexOf(SEPARATOR);
            if (idx != -1)
            {
               return name.substring(0, idx);
            }
        }        
        return name;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#checkDomainUser(java.lang.String)
     */
    public void checkDomainUser(String username)
    {
        ParameterCheck.mandatory("Username", username);
        
        String tenantDomain = getCurrentUserDomain();
        
        if (! tenantDomain.equals(DEFAULT_DOMAIN))
        {
            int idx2 = username.lastIndexOf(SEPARATOR);
            if ((idx2 > 0) && (idx2 < (username.length()-1)))
            {
                String tenantUserDomain = username.substring(idx2+1);
                
                if ((tenantUserDomain == null) || (! tenantDomain.equalsIgnoreCase(tenantUserDomain)))
                {
                    throw new TenantDomainMismatchException(tenantDomain, tenantUserDomain);
                }
            }
            else
            {
                throw new TenantDomainMismatchException(tenantDomain, null);
            }
        }
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#checkDomain(java.lang.String)
     */
    public void checkDomain(String name)
    {
        if (name == null)
        {
            return;
        }
        
        String nameDomain = null;
        
        int idx1 = name.indexOf(SEPARATOR);
        if (idx1 == 0)
        {
            int idx2 = name.indexOf(SEPARATOR, 1);
            nameDomain = name.substring(1, idx2);
        }
        
        String tenantDomain = getCurrentUserDomain();
        
        if (((nameDomain == null) && (! tenantDomain.equals(DEFAULT_DOMAIN))) || 
            ((nameDomain != null) && (! nameDomain.equals(tenantDomain))))
        {
            throw new AlfrescoRuntimeException("domain mismatch: expected = " + tenantDomain + ", actual = " + nameDomain);
        }
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getRootNode(org.alfresco.service.cmr.repository.NodeService, org.alfresco.service.cmr.search.SearchService, org.alfresco.service.namespace.NamespaceService, java.lang.String, org.alfresco.service.cmr.repository.NodeRef)
     */
    public NodeRef getRootNode(NodeService nodeService, SearchService searchService, NamespaceService namespaceService, String rootPath, NodeRef rootNodeRef)
    {
        ParameterCheck.mandatory("NodeService", nodeService);
        ParameterCheck.mandatory("SearchService", searchService);  
        ParameterCheck.mandatory("NamespaceService", namespaceService);
        ParameterCheck.mandatory("RootPath", rootPath);  
        ParameterCheck.mandatory("RootNodeRef", rootNodeRef); 
        
        //String username = AuthenticationUtil.getFullyAuthenticatedUser();
        StoreRef storeRef = rootNodeRef.getStoreRef();
        
        AuthenticationUtil.RunAsWork action = new GetRootNode(nodeService, searchService, namespaceService, rootPath, rootNodeRef, storeRef);
        return getBaseName(AuthenticationUtil.runAs(action, AuthenticationUtil.getSystemUserName()));
    }
    
    private class GetRootNode implements AuthenticationUtil.RunAsWork
    {
        NodeService nodeService;
        SearchService searchService;
        NamespaceService namespaceService;
        String rootPath;
        NodeRef rootNodeRef;
        StoreRef storeRef;
        GetRootNode(NodeService nodeService, SearchService searchService, NamespaceService namespaceService, String rootPath, NodeRef rootNodeRef, StoreRef storeRef)
        {
            this.nodeService = nodeService;
            this.searchService = searchService;
            this.namespaceService = namespaceService;
            this.rootPath = rootPath;
            this.rootNodeRef = rootNodeRef;
            this.storeRef = storeRef;
        }
        public NodeRef doWork() throws Exception
        {         
            // Get company home / root for the tenant domain
            // Do this as the System user in case the tenant user does not have permission
            // Connect to the repo and ensure that the store exists
            if (! nodeService.exists(storeRef))
            {
                throw new AlfrescoRuntimeException("Store not created prior to application startup: " + storeRef);
            }
            NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
            // Find the root node for this device
            List nodeRefs = searchService.selectNodes(storeRootNodeRef, rootPath, null, namespaceService, false);
            if (nodeRefs.size() > 1)
            {
                throw new AlfrescoRuntimeException("Multiple possible roots for device: \n" +
                        "   root path: " + rootPath + "\n" +
                        "   results: " + nodeRefs);
            }
            else if (nodeRefs.size() == 0)
            {
                // nothing found
                throw new AlfrescoRuntimeException("No root found for device: \n" +
                        "   root path: " + rootPath);
            }
            else
            {
                // we found a node
                rootNodeRef = nodeRefs.get(0);
            }   
            
            return rootNodeRef;
        }
    }
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#isTenantUser()
     */
    // TODO review usages (re: cloud external user => more than one domain)
    public boolean isTenantUser()
    {
        //return isTenantUser(AuthenticationUtil.getRunAsUser());
        return (! getCurrentUserDomain().equals(TenantService.DEFAULT_DOMAIN));
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#isTenantUser(java.lang.String)
     */
    // TODO review usages (re: cloud external user => more than one domain)
    public boolean isTenantUser(String username)
    {
        // can be null (e.g. for System user / during app ctx init)
        if (username != null) 
        {
            int idx = username.lastIndexOf(SEPARATOR);
            if ((idx > 0) && (idx < (username.length()-1)))
            {
               return true;
            }
        }
        return false;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#isTenantName(java.lang.String)
     */
    public boolean isTenantName(String name)
    {
        ParameterCheck.mandatory("name", name);
        
        int idx1 = name.indexOf(SEPARATOR);
        if (idx1 == 0)
        {
            int idx2 = name.indexOf(SEPARATOR, 1);
            if (idx2 != -1)
            {
                return true;
            }
        }
        
        return false;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getUserDomain(java.lang.String)
     */
    // TODO review usages (re: cloud external user => more than one domain)
    public String getUserDomain(String username)
    {
        // can be null (e.g. for System user / during app ctx init)
        if ((username != null) && AuthenticationUtil.isMtEnabled())
        {
            int idx = username.lastIndexOf(SEPARATOR);
            if ((idx > 0) && (idx < (username.length()-1)))
            {
               String tenantDomain = getTenantDomain(username.substring(idx+1));
               checkTenantEnabled(tenantDomain);
               
               return tenantDomain;
            }
        }
        
        return DEFAULT_DOMAIN; // default domain - non-tenant user
    }
    
    /**
     * Get the primary domain for the given user, if a tenant for that domain exists.
     * 
     * For user names of the form "user@tenantdomain", the tenant domain the part of the string 
     * after the @ symbol. A check is then made to see if tenant with that domain name exists.  
     * If it does, then the identified domain is returned. If no tenant exists then null is 
     * returned.
     * 
     * If the username does not end with a domain, as described above, then the default domain is 
     * returned. 
     */
    @Override public String getPrimaryDomain(String username)
    {
    	String result = null;
        // can be null (e.g. for System user / during app ctx init)
        if (username != null) 
        {
            int idx = username.lastIndexOf(SEPARATOR);
            if ((idx > 0) && (idx < (username.length()-1)))
            {
               String tenantDomain = getTenantDomain(username.substring(idx+1));
               
               if (getTenant(tenantDomain) != null)
               {
            	   result = tenantDomain;
               }
            }
            else
            {
            	result = DEFAULT_DOMAIN;
            }
        }
        
        return result; // default domain - non-tenant user
    }
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantUserService#getCurrentUserDomain()
     */
    public String getCurrentUserDomain()
    {
        String tenantDomain = TenantUtil.getCurrentDomain();
//        if (! tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
//        {
//            checkTenantEnabled(tenantDomain);
//        }
        return tenantDomain;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantUserService#getDomain(java.lang.String)
     */
    public String getDomain(String name)
    {
        return getDomain(name, false);
    }
    
    public String getDomain(String name, boolean checkCurrentDomain)
    {
        ParameterCheck.mandatory("name", name);
        
        String nameDomain = DEFAULT_DOMAIN;
        
        int idx1 = name.indexOf(SEPARATOR);
        if (idx1 == 0)
        {
            int idx2 = name.indexOf(SEPARATOR, 1);
            
            nameDomain = getTenantDomain(name.substring(1, idx2));
            
            if (checkCurrentDomain)
            {
                String tenantDomain = getCurrentUserDomain();
                
                if ((! tenantDomain.equals(DEFAULT_DOMAIN)) && (! tenantDomain.equals(nameDomain)))
                {
                    throw new AlfrescoRuntimeException("domain mismatch: expected = " + tenantDomain + ", actual = " + nameDomain);
                }
            }
        }
        
        return nameDomain;
    }
    
    /**
     * @deprecated
     * @return
     */
    public static String getMultiTenantDomainName(String name)
    {
        // Check that all the passed values are not null
        ParameterCheck.mandatory("name", name);
        
        int idx1 = name.indexOf(SEPARATOR);
        if (idx1 == 0)
        {
            int idx2 = name.indexOf(SEPARATOR, 1);
            if (idx2 != -1)
            {
                return name.substring(1, idx2);
            }
        }
        return DEFAULT_DOMAIN;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantUserService#getDomainUser(java.lang.String, java.lang.String)
     */
    public String getDomainUser(String baseUsername, String tenantDomain)
    {
        ParameterCheck.mandatory("baseUsername", baseUsername);
        
        if ((tenantDomain == null) || (tenantDomain.equals(DEFAULT_DOMAIN)))
        {
            return baseUsername;
        }
        else
        {
            if (baseUsername.contains(SEPARATOR))
            {
                throw new AlfrescoRuntimeException("Invalid base username: " + baseUsername);
            }
            
            if (tenantDomain.contains(SEPARATOR))
            {
                throw new AlfrescoRuntimeException("Invalid tenant domain: " + tenantDomain);
            }
            
            tenantDomain = getTenantDomain(tenantDomain);
            return baseUsername + SEPARATOR + tenantDomain;
        }
    }
    
    protected void checkTenantEnabled(String tenantDomain)
    {
        Tenant tenant = getTenant(tenantDomain);
        // note: System user can access disabled tenants
        if (tenant == null || !AuthenticationUtil.isRunAsUserTheSystemUser() && !tenant.isEnabled())
        {
            throw new TenantDisabledException(tenantDomain);
        }
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantService#getTenant(java.lang.String)
     */
    public Tenant getTenant(String tenantDomain)
    {
        TenantEntity tenantEntity = tenantAdminDAO.getTenant(tenantDomain);
        Tenant tenant = null;
        if (tenantEntity != null)
        {
            tenant = new Tenant(tenantEntity.getTenantDomain(), tenantEntity.getEnabled(), tenantEntity.getContentRoot(), null);
        }
        return tenant;
    }
    
    /* (non-Javadoc)
     * @see org.alfresco.repo.tenant.TenantUserService#isEnabled()
     */
    public boolean isEnabled()
    {
        return AuthenticationUtil.isMtEnabled();
    }
    
    private String getTenantDomain(String tenantDomain)
    {
        return tenantDomain.toLowerCase(I18NUtil.getLocale());
    }
}