package ${packageName}

import org.apache.commons.lang.builder.HashCodeBuilder

class ${userClassName}${groupClassName} implements Serializable {

	private static final long serialVersionUID = 1

	${userClassName} ${userClassProperty}
	${groupClassName} ${groupClassProperty}

	boolean equals(other) {
		if (!(other instanceof ${userClassName}${groupClassName})) {
			return false
		}

		other.${userClassProperty}?.id == ${userClassProperty}?.id &&
		other.${groupClassProperty}?.id == ${groupClassProperty}?.id
	}

	int hashCode() {
		def builder = new HashCodeBuilder()
		if (${userClassProperty}) builder.append(${userClassProperty}.id)
		if (${groupClassProperty}) builder.append(${groupClassProperty}.id)
		builder.toHashCode()
	}

	static ${userClassName}${groupClassName} get(long ${userClassProperty}Id, long ${groupClassProperty}Id) {
		${userClassName}${groupClassName}.where {
			${userClassProperty} == ${userClassName}.load(${userClassProperty}Id) &&
			${groupClassProperty} == ${groupClassName}.load(${groupClassProperty}Id)
		}.get()
	}

	static boolean exists(long ${userClassProperty}Id, long ${groupClassProperty}Id) {
		${userClassName}${groupClassName}.where {
			${userClassProperty} == ${userClassName}.load(${userClassProperty}Id) &&
			${groupClassProperty} == ${groupClassName}.load(${groupClassProperty}Id)
		}.count() > 0
	}

	static ${userClassName}${groupClassName} create(${userClassName} ${userClassProperty}, ${groupClassName} ${groupClassProperty}, boolean flush = false) {
		def instance = new ${userClassName}${groupClassName}(${userClassProperty}: ${userClassProperty}, ${groupClassProperty}: ${groupClassProperty})
		instance.save(flush: flush, insert: true)
		instance
	}

	static boolean remove(${userClassName} u, ${groupClassName} g, boolean flush = false) {
		if (u == null || g == null) return false

		int rowCount = ${userClassName}${groupClassName}.where {
			${userClassProperty} == ${userClassName}.load(u.id) &&
			${groupClassProperty} == ${groupClassName}.load(g.id)
		}.deleteAll()

		if (flush) { ${userClassName}${groupClassName}.withSession { it.flush() } }

		rowCount > 0
	}

	static void removeAll(${userClassName} u, boolean flush = false) {
		if (u == null) return

		${userClassName}${groupClassName}.where {
			${userClassProperty} == ${userClassName}.load(u.id)
		}.deleteAll()

		if (flush) { ${userClassName}${groupClassName}.withSession { it.flush() } }
	}

	static void removeAll(${groupClassName} g, boolean flush = false) {
		if (g == null) return

		${userClassName}${groupClassName}.where {
			${groupClassProperty} == ${groupClassName}.load(g.id)
		}.deleteAll()

		if (flush) { ${userClassName}${groupClassName}.withSession { it.flush() } }
	}

	static constraints = {
		${userClassProperty} validator: { ${userClassName} u, ${userClassName}${groupClassName} ug ->
			if (ug.${groupClassProperty} == null) return
			boolean existing = false
			${userClassName}${groupClassName}.withNewSession {
				existing = ${userClassName}${groupClassName}.exists(u.id, ug.${groupClassProperty}.id)
			}
			if (existing) {
				return 'userGroup.exists'
			}
		}
	}

	static mapping = {
		id composite: ['${groupClassProperty}', '${userClassProperty}']
		version false
	}
}
