package mit.roles ;

public class People
	implements	roles.People
		, 	java.io.Serializable
{
	protected sql.Rows rows = null ;
	protected mit.roles.RolesFactory rolesFactory = null ;

	public boolean hasMorePeople()
		throws Exception
	{
		if( null != this.rows )
		{
			return rows.hasMoreRows() ;
		}
		return false ;
	}

	public roles.Person nextPerson()
		throws Exception
	{
		if( null != this.rows )
		{
			return getPerson( this.rows.getColumnNames() , this.rows.nextRow() ) ;
		}
		throw new roles.RolesException( roles.RolesException.PEOPLEENUMERATIONFAILED ) ;
	}

	public static roles.People getWhoCanDo
		( mit.roles.RolesFactory rolesFactory
		, roles.Function function
		, Boolean isActiveNow
		)
		throws Exception
	{
		return
			getPeopleInternal
				( rolesFactory
				, function
				, null
				, isActiveNow
				, null
				, null
				) ;
	}

	public static roles.People getWhoCanDo
		( mit.roles.RolesFactory rolesFactory
		, roles.Function function
		, roles.Qualifier qualifier
		, Boolean isActiveNow
		)
		throws Exception
	{
		return
			getPeopleInternal
				( rolesFactory
				, function
				, qualifier
				, isActiveNow
				, null
				, null
				) ;
	}

	public static roles.People getWhoCanDo
		( mit.roles.RolesFactory rolesFactory
		, roles.Qualifier qualifier
		, Boolean isActiveNow
		)
		throws Exception
	{
		return
			getPeopleInternal
				( rolesFactory
				, null
				, qualifier
				, isActiveNow
				, null
				, null
				) ;
	}

	public static roles.People getWhoCanDo
		( mit.roles.RolesFactory rolesFactory
		, roles.FunctionCategory functionCategory
		, Boolean isActiveNow
		)
		throws Exception
	{
		return
			getPeopleInternal
				( rolesFactory
				, null
				, null
				, functionCategory.getCategory()
				, null
				, null
				, null
				, isActiveNow.booleanValue() ? "Y" : "N"
				, null
				, null
			) ;
	}

	public static roles.People getWhoCanDo
		( mit.roles.RolesFactory rolesFactory
		, roles.FunctionCategory functionCategory
		, roles.Qualifier qualifier
		, Boolean isActiveNow
		)
		throws Exception
	{
		return
			getPeopleInternal
				( rolesFactory
				, null
				, null
				, functionCategory.getCategory()
				, null
				, qualifier.getCode()
				, qualifier.getQualifierType().getType()
				, isActiveNow.booleanValue() ? "Y" : "N"
				, null
				, null
			) ;
	}

	private static roles.People getPeopleInternal
		( mit.roles.RolesFactory rolesFactory
		, roles.Function function
		, roles.Qualifier qualifier
		, Boolean isActiveNow
		, Boolean expandFunctions
		, Boolean expandQualifiers
		)
		throws Exception
	{
		String functionCategory = ( null == function ) ? null : ( ( null == function.getFunctionCategory() ) ? null : function.getFunctionCategory().getCategory() ) ;
		String functionName = ( null == function ) ? null : function.getName() ;
		String functionId = ( null == function ) ? null : function.getId().toString() ;
		String qualifierType = ( null == qualifier ) ? null : ( ( null == qualifier.getQualifierType() ) ? null : qualifier.getQualifierType().getType() ) ;
		String qualifierCode = ( null == qualifier ) ? null : qualifier.getCode() ;
		String qualifierId = ( null == qualifier ) ? null : qualifier.getId().toString() ;
		String expandFunctionsStr = expandFunctions.booleanValue() ? "Y" : "N" ;
		String expandQualifiersStr = expandQualifiers.booleanValue() ? "Y" : "N" ;
		String isActiveNowStr = isActiveNow.booleanValue() ? "Y" : "N" ;
		mit.roles.People people
			= getPeopleInternal
				( rolesFactory
				, functionId
				, functionName
				, functionCategory
				, qualifierId
				, qualifierCode
				, qualifierType
				, isActiveNowStr
				, expandFunctionsStr
				, expandQualifiersStr
				) ;
		if( null == people.rows )
		{
			if( function.isFoundInRoles().booleanValue() )
			{
				if( qualifier.isFoundInRoles().booleanValue() )
				{
					return people ;
				}
				throw new roles.RolesException( roles.RolesException.QUALIFIERNOTFOUNDINROLES ) ;
			}
			throw new roles.RolesException( roles.RolesException.FUNCTIONNOTFOUNDINROLES ) ;
		}
		return null ;
	}

	private static mit.roles.People getPeopleInternal
		( mit.roles.RolesFactory rolesFactory
		, String functionIdStr
		, String functionName
		, String functionCategory
		, String qualifierIdStr
		, String qualifierCode
		, String qualifierType
		, String isActiveNowStr
		, String expandFunctionsStr
		, String expandQualifiersStr
		)
		throws Exception
	{
		try
		{
			String sqlQuery
				= getPeopleSQL
					( rolesFactory
					, expandQualifiersStr
					, isActiveNowStr
					, functionCategory
					, functionName
					, functionIdStr
					, qualifierType
					, qualifierCode
					, qualifierIdStr
					) ;
			return getPeople( rolesFactory , sqlQuery ) ;
		}
		catch( Exception ex )
		{
			throw new roles.RolesException
			( new String
				( roles.RolesException.QUERYAUTHORIZATIONFAILED
				+ ex.getMessage()
				)
			) ;
		}
	}

	protected static mit.roles.People getPeople
		( mit.roles.RolesFactory rolesFactory
		, String sqlQuery
		)
		throws Exception
	{
		try
		{
			if( null != sqlQuery )
			{
				sql.Connection connection = rolesFactory.getConnection() ;
				sql.Table table
					= connection.executeQuery
						( sqlQuery
						) ;
				if( null != table )
				{
					mit.roles.People people = new mit.roles.People() ;
					people.rolesFactory = rolesFactory ;
					people.rows = table.getRows() ;
					return people ;
				}
			}
		}
		catch( Exception ex )
		{
			throw new roles.RolesException( ex.getMessage() ) ;
		}
		throw new roles.RolesException
			( roles.RolesException.QUERYAUTHORIZATIONFAILED ) ;
	}

	/**
	 * @param algorithm is "WHO_CAN_DO"
	 * @param expandQualifiers is either "Y" or "N", default is "N"
	 * @param isActiveNow is either "Y" or "N", default is "N"
	 */
	private static String getPeopleSQL
		( mit.roles.RolesFactory rolesFactory
		, String expandQualifiers
		, String isActiveNow
		, String functionCategory
		, String functionName
		, String functionId
		, String qualifierType
		, String qualifierCode
		, String qualifierId
		)
		throws Exception
	{
		if( null != rolesFactory )
		{
			sql.Connection connection = rolesFactory.getConnection() ;
			Object[] args = new Object[ 11 ] ;
			args[ 0 ] = "WHO_CAN_DO" ;
			args[ 1 ] = expandQualifiers ;
			args[ 2 ] = isActiveNow ;
			args[ 3 ] = null ;
			args[ 4 ] = functionCategory ;
			args[ 5 ] = functionName ;
			args[ 6 ] = functionId ;
			args[ 7 ] = qualifierType ;
			args[ 8 ] = qualifierCode ;
			args[ 9 ] = qualifierId ;
			args[ 10 ] = null ;
			int[] columnTypes = new int[ 12 ] ;
			columnTypes[ 0 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 1 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 2 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 3 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 4 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 5 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 6 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 7 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 8 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 9 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 10 ] = java.sql.DatabaseMetaData.procedureColumnIn ;
			columnTypes[ 11 ] = java.sql.DatabaseMetaData.procedureColumnOut ;
			int[] dataTypes = new int[ 12 ] ;
			dataTypes[ 0 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 1 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 2 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 3 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 4 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 5 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 6 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 7 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 8 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 9 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 10 ] = java.sql.Types.VARCHAR ;
			dataTypes[ 11 ] = java.sql.Types.VARCHAR ;
			sql.Table tab =
				connection.callProcedure
					( "ROLESAPI_GET_SQL_AUTH1"
					, args
					, columnTypes
					, dataTypes
					) ;
			if( null != tab )
			{
				sql.Rows rows = tab.getRows() ;
				if( rows.hasMoreRows() )
				{
 					Object[] row = rows.nextRow() ;
					String sql = ( String ) row[ 0 ] ;
System.out.println
	( "Sql string for:"
	+ "\nexpandQualifiers: " + expandQualifiers
	+ "\nisActiveNow: " + isActiveNow
	+ "\nfunctionCategory: " + functionCategory
	+ "\nfunctionName: " + functionName
	+ "\nfunctionId: " + functionId
	+ "\nqualifierType: " + qualifierType
	+ "\nqualifierCode: " + qualifierCode
	+ "\nqualifierid: " + qualifierId
	+ "\ngenerated sql:\n"
	+ sql
	) ;
					return sql ;
				}
			}
		}
		throw new roles.RolesException( roles.RolesException.PEOPLEENUMERATIONFAILED ) ;
	}

	private roles.Person getPerson
		( String[] columnNames
		, Object[] row
		)
		throws Exception
	{
		if( ( null != columnNames ) && ( null != row ) )
		{
			java.util.Properties properties = new java.util.Properties() ;
			for( int i = 0 ; columnNames.length != i ; i ++ )
			{
				properties.put( columnNames[ i ] , row[ i ] ) ;
			}
			return new mit.roles.Person( this.rolesFactory , properties ) ;
		}
		throw new roles.RolesException( roles.RolesException.PEOPLEENUMERATIONFAILED ) ;
	}

}
