/*
 * Copyright 2005-2008 Les Hazlewood, Jeremy Haile
 *
 * Licensed 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 org.jsecurity.realm;

import org.jsecurity.authc.Account;
import org.jsecurity.authc.credential.CredentialsMatcher;
import org.jsecurity.authz.*;
import org.jsecurity.authz.permission.PermissionResolver;
import org.jsecurity.authz.permission.PermissionResolverAware;
import org.jsecurity.authz.permission.WildcardPermissionResolver;
import org.jsecurity.cache.Cache;
import org.jsecurity.cache.CacheManager;
import org.jsecurity.util.Initializable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * An <tt>AuthorizingRealm</tt> extends the <tt>AuthenticatingRealm</tt>'s capabilities by adding Authorization
 * (access control) support via the use of {@link AuthorizingAccount AuthorizingAccount} instances.
 *
 * <p>This implementation can only support Authorization operations if the subclass implementation's
 * {@link #getAccount(Object) getAccount(principal)} method returns an {@link AuthorizingAccount AuthorizingAccount}.
 * <p>If it does not, subclasses <em>must</em> override all {@link org.jsecurity.authz.Authorizer Authorizer} methods,
 * since the JSecurity default implementations cannot infer Role/Permission assignments via anything but
 * <tt>AuthorizingAccount</tt> instances.
 *
 * <p>If your Realm implementation does not want to deal with <tt>AuthorizingAccount</tt> constructs, you are of course
 * free to subclass the {@link AuthorizingRealm AuthorizingRealm} directly and implement the remaining
 * interface methods yourself.  Many people do this if they want to have better control over how the
 * Role and Permission checks occur for their specific data source.
 *
 * @author Les Hazlewood
 * @author Jeremy Haile
 * @since 0.2
 */
public abstract class AuthorizingRealm extends AuthenticatingRealm implements Initializable, PermissionResolverAware {

    /*--------------------------------------------
    |             C O N S T A N T S             |
    ============================================*/
    /**
     * The default postfix appended to the realm name for caching Accounts.
     */
    private static final String DEFAULT_ACCOUNT_CACHE_POSTFIX = "-accounts";

    private static int INSTANCE_COUNT = 0;

    /*--------------------------------------------
    |    I N S T A N C E   V A R I A B L E S    |
    ============================================*/
    /**
     * The cache used by this realm to store Accounts associated with individual Subject principals.
     */
    private Cache accountCache = null;
    private String accountCacheName = null;

    private PermissionResolver permissionResolver = new WildcardPermissionResolver();

    /*--------------------------------------------
    |         C O N S T R U C T O R S           |
    ============================================*/
    public AuthorizingRealm() {
    }

    public AuthorizingRealm(CacheManager cacheManager) {
        super(cacheManager);
    }

    public AuthorizingRealm(CredentialsMatcher matcher) {
        super(matcher);
    }

    public AuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
        super(cacheManager, matcher);
    }

    /*--------------------------------------------
    |  A C C E S S O R S / M O D I F I E R S    |
    ============================================*/
    public void setAccountCache(Cache accountCache) {
        this.accountCache = accountCache;
    }

    public Cache getAccountCache() {
        return this.accountCache;
    }

    public String getAccountCacheName() {
        return accountCacheName;
    }

    public void setAccountCacheName(String accountCacheName) {
        this.accountCacheName = accountCacheName;
    }

    public PermissionResolver getPermissionResolver() {
        return permissionResolver;
    }

    public void setPermissionResolver(PermissionResolver permissionResolver) {
        this.permissionResolver = permissionResolver;
    }

    /*--------------------------------------------
    |               M E T H O D S               |
    ============================================*/
    /**
     * Initializes this realm and potentially enables a cache, depending on configuration.
     *
     * <p>When this method is called, the following logic is executed:
     * <ol>
     * <li>If the {@link #setAccountCache cache} property has been set, it will be
     * used to cache the Account objects returned from {@link #getAccount getAccount}
     * method invocations.
     * All future calls to <tt>getAccount</tt> will attempt to use this Account cache first
     * to alleviate any potentially unnecessary calls to an underlying data store.</li>
     * <li>If the {@link #setAccountCache cache} property has <b>not</b> been set,
     * the {@link #setCacheManager cacheManager} property will be checked.
     * If a <tt>cacheManager</tt> has been set, it will be used to create an Account
     * <tt>cache</tt>, and this newly created cache which will be used as specified in #1.</li>
     * <li>If neither the {@link #setAccountCache(org.jsecurity.cache.Cache) cache}
     * or {@link #setCacheManager(org.jsecurity.cache.CacheManager) cacheManager}
     * properties are set, caching will be disabled and Account lookups will be delegated to
     * subclass implementations for each authorization check.</li>
     * </ol>
     */
    public final void init() {
        initAccountCache();
        afterAccountCacheSet();
    }

    protected void afterAccountCacheSet() {
    }

    protected void initAccountCache() {
        if (log.isTraceEnabled()) {
            log.trace("Initializing account cache.");
        }

        Cache cache = getAccountCache();

        if (cache == null) {

            if (log.isDebugEnabled()) {
                log.debug("No cache implementation set.  Checking cacheManager...");
            }

            CacheManager cacheManager = getCacheManager();

            if (cacheManager != null) {
                String cacheName = getAccountCacheName();
                if (cacheName == null) {
                    //Simple default in case they didn't provide one:
                    cacheName = getClass().getName() + "-" + INSTANCE_COUNT++ + DEFAULT_ACCOUNT_CACHE_POSTFIX;
                    setAccountCacheName(cacheName);
                }
                if (log.isDebugEnabled()) {
                    log.debug("CacheManager [" + cacheManager + "] has been configured.  Building " +
                            "Account cache named [" + cacheName + "]");
                }
                cache = cacheManager.getCache(cacheName);
                setAccountCache(cache);
            } else {
                if (log.isInfoEnabled()) {
                    log.info("No cache or cacheManager properties have been set.  Account caching is " +
                            "disabled.");
                }
            }
        }
    }

    /**
     * Template-pattern method to be implemented by subclasses to retrieve the Account for the given principal.
     *
     * @param principal the primary identifying principal of the Account that should be retrieved.
     * @return the Account associated with this principal.
     */
    protected abstract AuthorizingAccount doGetAccount(Object principal);

    /**
     * <p>Retrieves Account information for the given account principal.
     *
     * <p>If caching is enabled, the account cache will be checked first and if found, will return the cached account.
     * If caching is disabled, or there is a cache miss from the cache lookup, the Account will be looked up from
     * the underlying data store via the {@link #doGetAccount(Object)} method, which must be implemented by subclasses.
     *
     * <p>If caching is enabled, the retrieved Account from <tt>doGetAccount</tt> will be added to the account cache
     * first and then returned.
     *
     * @param principal the primary identifying principal of the Account that should be retrieved.
     * @return the Account associated with this princpal.
     */
    protected Account getAccount(Object principal) {

        if (principal == null) {
            return null;
        }

        Account account = null;

        if (log.isTraceEnabled()) {
            log.trace("Retrieving Account for principal [" + principal + "]");
        }

        Cache accountCache = getAccountCache();
        if (accountCache != null) {
            if (log.isTraceEnabled()) {
                log.trace("Attempting to retrieve the Account from cache.");
            }
            account = (Account) accountCache.get(principal);
            if (log.isTraceEnabled()) {
                if (account == null) {
                    log.trace("No Account found in cache for principal [" + principal + "]");
                } else {
                    log.trace("Account found in cache for principal [" + principal + "]");
                }
            }
        }


        if (account == null) {
            // Call template method if tbe Account was not found in a cache
            account = doGetAccount(principal);
            // If the account is not null and the cache has been created, then cache the account.
            if (account != null && accountCache != null) {
                if (log.isTraceEnabled()) {
                    log.trace("Caching Account [" + principal + "].");
                }
                accountCache.put(principal, account);
            }
        }

        return account;
    }

    protected AuthorizingAccount getAuthorizingAccount(Object principal) {
        if (principal == null) {
            throw new AuthorizationException("Specified principal argument is null and authorization checks cannot " +
                    "occur without a known account identity.");
        }
        Account account = getAccount(principal);
        assertNotNullAccount(principal, account);
        assertAuthorizingAccount(account);
        return (AuthorizingAccount) account;
    }

    protected void assertNotNullAccount(Object subjectPrincipal, Account account) {
        if (account == null) {
            throw new MissingAccountException("No Account found for Subject principal [" +
                    subjectPrincipal + "]");
        }
    }

    protected void assertAuthorizingAccount(Account account) {
        if (!(account instanceof AuthorizingAccount)) {
            String msg = "Underlying Account instance [" + account + "] does not implement the " +
                    AuthorizingAccount.class.getName() + " interface.  The JSecurity " +
                    AuthorizingRealm.class.getName() + " class and its default implementations can only provide default " +
                    "authorization (access control) support for Accounts that implement this interface.  If you do not " +
                    "wish to implement this interface, you will need to override all of this Realm's Authorizer methods " +
                    "to perform the authorization check explicitly.\n\nNote that there is nothing wrong with this " +
                    "approach since it often gives finer control of how authorization checks occur, but you would have " +
                    "to override these methods explicitly since JSecurity can't infer your application's security " +
                    "data model.";
            throw new UnsupportedAccountException(msg);
        }
    }


    public boolean isPermitted(Object subjectIdentifier, String permission) {
        Permission p = getPermissionResolver().resolvePermission(permission);
        return isPermitted(subjectIdentifier, p);
    }

    public boolean isPermitted(Object principal, Permission permission) {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        return account.isPermitted(permission);
    }

    public boolean[] isPermitted(Object subjectIdentifier, String... permissions) {
        List<Permission> perms = new ArrayList<Permission>(permissions.length);
        for (String permString : permissions) {
            perms.add(getPermissionResolver().resolvePermission(permString));
        }
        return isPermitted(subjectIdentifier, perms);
    }

    public boolean[] isPermitted(Object principal, List<Permission> permissions) {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        return account.isPermitted(permissions);
    }

    public boolean isPermittedAll(Object subjectIdentifier, String... permissions) {
        if (permissions != null && permissions.length > 0) {
            Collection<Permission> perms = new ArrayList<Permission>(permissions.length);
            for (String permString : permissions) {
                perms.add(getPermissionResolver().resolvePermission(permString));
            }
            return isPermittedAll(subjectIdentifier, perms);
        }
        return false;
    }

    public boolean isPermittedAll(Object principal, Collection<Permission> permissions) {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        return account != null && account.isPermittedAll(permissions);
    }

    public void checkPermission(Object subjectIdentifier, String permission) throws AuthorizationException {
        Permission p = getPermissionResolver().resolvePermission(permission);
        checkPermission(subjectIdentifier, p);
    }

    public void checkPermission(Object principal, Permission permission) throws AuthorizationException {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        account.checkPermission(permission);
    }

    public void checkPermissions(Object subjectIdentifier, String... permissions) throws AuthorizationException {
        if (permissions != null) {
            for (String permString : permissions) {
                checkPermission(subjectIdentifier, permString);
            }
        }
    }

    public void checkPermissions(Object principal, Collection<Permission> permissions) throws AuthorizationException {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        account.checkPermissions(permissions);
    }

    public boolean hasRole(Object principal, String roleIdentifier) {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        return account.hasRole(roleIdentifier);
    }

    public boolean[] hasRoles(Object principal, List<String> roleIdentifiers) {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        boolean[] result = new boolean[roleIdentifiers != null ? roleIdentifiers.size() : 0];
        if (account != null) {
            result = account.hasRoles(roleIdentifiers);
        }
        return result;
    }

    public boolean hasAllRoles(Object principal, Collection<String> roleIdentifiers) {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        return account != null && account.hasAllRoles(roleIdentifiers);
    }

    public void checkRole(Object principal, String role) throws AuthorizationException {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        account.checkRole(role);
    }

    public void checkRoles(Object principal, Collection<String> roles) throws AuthorizationException {
        AuthorizingAccount account = getAuthorizingAccount(principal);
        account.checkRoles(roles);
    }

    /**
     * If account caching is enabled, this will remove the account from the cache.  Subclasses are free to override
     * for additional behavior, but be sure to call <tt>super.onLogout</tt> to ensure cache cleanup.
     *
     * @param accountPrincipal the application-specific Subject/user identifier.
     */
    public void onLogout(Object accountPrincipal) {
        Cache cache = getAccountCache();
        //cache instance will be non-null if caching is enabled:
        if (cache != null && accountPrincipal != null) {
            cache.remove(accountPrincipal);
        }
    }
}
