/* 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.
 */
package com.we_lab_doc.spacecard.model

import com.we_lab_doc.spacecard.model.abstracts.*
import com.we_lab_doc.spacecard.utils.*
import com.we_lab_doc.spacecard.utils.ModelUtils as MU

/**
 * @author Shigeru GOUGI
 * @since 0.1
 *        <p/>
 *        Created: February 13, 2008
 */ 
final class Role implements SpaceCardDomainModel {
	boolean remove() {
		for ( user in ModelUtils.cloneCollection(users)) {
			user.removeFromRoles(this)
		}
		return ModelUtils.delete(this)
	}
	////
	boolean isAdminAuthority() {
		return this.authority == AuthorityType.ADMIN		
	}
	boolean isUserAuthority() {
		return this.authority == AuthorityType.USER
	}
	////
	static boolean hasAdminAuthority(Collection roles) {
		assert roles != null
		for ( role in roles ) {
			if(role.isAdminAuthority()) 
				return true
		}
		return false
	}
	static boolean hasUserAuthority(Collection roles) {
		assert roles != null
		for (role in roles ) {
			if(role.isUserAuthority()) 
				return true
		}
		return false
	}
	static Role getSupervisorRole() {
		def roles = Role.select("where r.organization.isSupervisorCommunity=true")
		if(roles.size() == 0) return null
		return roles[0]
	}
	static Collection getRoles(User user, Organization org) {
		assert user != null && org != null
		def roles = Role.selectDistinct("join r.users as u where u=:user and r.organization=:org", [user:user, org:org])
		return roles
	}
	static Role getRole(String authority, Organization organization){
		assert authority != null && organization != null
		def roles = Role.select("where r.authority=:authority and r.organization=:organization", [authority:authority, organization:organization])
		if(roles.size() == 0) return null
		return roles[0]
	}
	////
	static Role createAdminRole(Organization organization) {
		assert organization != null
		return create(AuthorityType.ADMIN, organization)		
	}
	static Role createUserRole(Organization organization) {
		assert organization != null
		return create(AuthorityType.USER, organization)
	}
	static Role create(String authority, Organization organization) {
		assert authority != null && organization != null
		def role = new Role(authority:authority)
		organization.addToRoles(role)
		return role		
	}
	/////////////////////////////////////////////
	def addToUsers(User obj) {
		return CollectionBugEvasion.addToForBidirectionalManyToMany(
					this, Set.class, obj, User.class, "users", "roles"  
				)	
	}
	def removeFromUsers(User obj) {
		return CollectionBugEvasion.removeFromForBidirectionalManyToMany(
					this, obj, "users", "roles"   
				)		
	}	
	/////////////////////////////////////////////
	def beforeInsert = {
		ModelUtils.insertLog(this)
	}
	def beforeUpdate = {
		ModelUtils.updateLog(this)		
	}
	def beforeDelete = {
		ModelUtils.deleteLog(this)		
	}	
	/////////////////////////////////////////////
	static transients  = [
	                      'adminAuthority',
	                      'userAuthority'
	                     ]
	static belongsTo   = [organization:Organization]
	static hasMany     = [users:User]
	static constraints = {
		authority(blank:false)
		organization(nullable:false)
		// TODO:  authority と organization でユニークに 
	}
	/////////////////////////////////////////////
	String authority
}