/* Copyright 2008 we-lab-doc! (http://www.we-lab-doc.com/) 
 *
 * 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.
 */
import com.we_lab_doc.spacecard.ac.*
import com.we_lab_doc.spacecard.model.*
import org.springframework.web.context.request.RequestContextHolder as RCH
import com.we_lab_doc.spacecard.bean.annotation.SpaceCardCustomBean

/**
 * @author Shigeru GOUGI
 * @since 0.1
 *        <p/>
 *        Created: February 24, 2008
 */
@SpaceCardCustomBean
class DefaultAccessControlManager implements AccessControlManager {
	boolean authenticate(String account, String password) {
		if(account == null || password == null) return false
		def user = getActiveAuthUserByAccount(account)
		if(user == null) return false
		def encodedPassword = User.encodePassword(password)
		if (user.password == encodedPassword)  {
			_setLoggedInAuthUser(user)
			return true
		}
		_setLoggedInAuthUser(null)
		return false
	}
	void unauthenticate() {
		_setLoggedInAuthUser(null)		
	}
	AuthUser getLoggedInAuthUser() {
		return _getLoggedInAuthUser()
	}	
	boolean isLoggedIn() {
		return _getLoggedInAuthUser() != null
	}
	boolean isNotLoggedIn(){
		return !isLoggedIn()
	}
	boolean checkPermission(AuthUser user, AccessControllable ac) {
		if(ac == null) return false
		return _checkPermission(user, ac.getPermission())
	}
	AuthUser getAuthUserByAccount(String account){
		return User.findByAccount(account)
	}
	AuthUser getActiveAuthUserByAccount(String account){
		return User.findByAccountAndActive(account, true)
	}
	// boolean canRead(AuthUser user, AccessControllable ac){}
	// boolean canWrite(AuthUser user, AccessControllable ac){}
	// boolean canDelete(AuthUser user, AccessControllable ac){}
	/////////////////////////////////////////////////////////////////
	private def _getLoggedInAuthUserId() {
		return _getSession()?.getAttribute('DefaultAccessControlManager.loggedInAuthUserId')
	}
	private void _setLoggedInAuthUserId(id) {
		_getSession()?.setAttribute('DefaultAccessControlManager.loggedInAuthUserId', id)
	}
	private def _getLoggedInAuthUser() {
		def user = _getRequest()?.getAttribute('DefaultAccessControlManager.loggedInAuthUser')
		if (! user) {
			def userId = _getLoggedInAuthUserId()
			if (userId) {
				user = User.get(userId)
				_setLoggedInAuthUser(user)
			}
		}
		return user
	}
	private void _setLoggedInAuthUser(user) {
		_setLoggedInAuthUserId(user?.id)
		_getRequest()?.setAttribute('DefaultAccessControlManager.loggedInAuthUser', user)
	}
	private boolean _checkPermission(sessionOrUser, Permission permission) {
		if(sessionOrUser == null) return false
		if(permission == null) return false
		def user = (sessionOrUser instanceof AuthUser) ? sessionOrUser : getAuthUserFromSession(sessionOrUser)
		def rt = permission.check(user)
		return rt
	}
	private def _getSession() {
		return RCH.currentRequestAttributes()?.session
	}
	private def _getRequest() {
		return RCH.currentRequestAttributes()?.request
	}	
}