/*******************************************************************************
 * Copyright 2Fi Business Solutions Ltd.
 *
 * This code is copyrighted. Under no circumstances should any party, people,
 * or organization should redistribute any portions of this code in any form,
 * either verbatim or through electronic media, to any third parties, unless
 * under explicit written permission by 2Fi Business Solutions Ltd.
 ******************************************************************************/
package com.ffii.tbms.user.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.ffii.core.dao.JdbcDao;
import com.ffii.core.utils.MapUtils;
import com.ffii.core.web.AbstractService;

/**
 * Service for managing users authorities
 * 
 * @author Patrick
 */
@Service
public class AuthService extends AbstractService {

	@Autowired
	private JdbcDao jdbcDao;

	@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = true)
	public List<Map<String, Object>> search(int userId) {

		/*
		SELECT
		a.module,
		a.authority,
		a.name,
		EXISTS(SELECT 1 FROM users_authorities WHERE authority = a.authority AND userId = :userId) AS v
		FROM authorities a
		WHERE a.deleted = 0
		
		ORDER BY a.id
		*/
		StringBuilder sql = new StringBuilder("SELECT"
				+ " a.module,"
				+ " a.authority,"
				+ " a.name,"
				+ " EXISTS(SELECT 1 FROM users_authorities WHERE authority = a.authority AND userId = :userId) AS v"
				+ " FROM authorities a");

		sql.append(" ORDER BY a.authority");

		return jdbcDao.queryForList(sql.toString(), MapUtils.toHashMap("userId", userId));
	}

	@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
	public int[] batchInsertUsersAuthorities(Map<String, Object>[] batchValues) {

		String sql = "INSERT IGNORE INTO users_authorities"
				+ " (userId, authority)"
				+ " VALUES"
				+ " (:userId, :authority)";

		return jdbcDao.executeBatchUpdate(sql, batchValues);
	}

	@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
	public int[] batchDeleteUsersAuthorities(Map<String, Object>[] batchValues) {

		String sql = "DELETE FROM users_authorities"
				+ " WHERE userId = :userId AND authority = :authority";

		return jdbcDao.executeBatchUpdate(sql, batchValues);
	}

	@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
	public List<Map<String, Object>> findUserWithAuth(Map<String, Object> args) {

		StringBuilder sql = new StringBuilder("SELECT * FROM users_authorities"
				+ " WHERE 1=1 ");
		if (args != null) {
			if (args.containsKey("authority")) sql.append(" AND authority = :authority  ");
			if (args.containsKey("ignoreUserId")) sql.append(" AND userId != :ignoreUserId  ");
		}

		return jdbcDao.queryForList(sql.toString(), args);
	}

	@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = true)
	public List<Map<String, Object>> list() {

		/*
		SELECT a.* 
		FROM 
		authorities a;
		
		*/
		StringBuilder sql = new StringBuilder("SELECT"
				+ " a.*"
				+ " FROM authorities a");

		sql.append(" ORDER BY a.authority");

		return jdbcDao.queryForList(sql.toString(), null);
	}

}
