
USE parts;

-- Clear previous proc
DROP PROCEDURE IF EXISTS p_dog_get_many_user;


DELIMITER //
CREATE PROCEDURE p_dog_get_many_user (
	IN a_id_user INT
    , IN a_auth0_id_user VARCHAR(200)
	, IN a_get_all_user BIT
	, IN a_get_inactive_user BIT
	, IN a_ids_user TEXT
    , IN a_auth0_ids_user TEXT
    , IN a_names_user TEXT
    , IN a_emails_user TEXT
    , IN a_require_all_id_search_filters_met BIT
    , IN a_require_any_id_search_filters_met BIT
    , IN a_require_all_non_id_search_filters_met BIT
    , IN a_require_any_non_id_search_filters_met BIT
    , IN a_debug BIT
)
BEGIN
    DECLARE v_code_type_error_bad_data VARCHAR(50);
    DECLARE v_guid BINARY(36);
    DECLARE v_has_filter_user_auth0_id BIT;
    DECLARE v_has_filter_user_id BIT;
    DECLARE v_has_filter_user_name BIT;
    DECLARE v_id_access_level_admin INT;
    DECLARE v_id_access_level_view INT;
    DECLARE v_id_minimum INT;
    DECLARE v_id_permission_dog_admin INT;
    DECLARE v_id_permission_user INT;
    DECLARE v_id_permission_user_admin INT;
    DECLARE v_id_type_error_bad_data INT;
    DECLARE v_ids_permission_required VARCHAR(4000);
    DECLARE v_ids_user TEXT;
    DECLARE v_is_new BIT;
    DECLARE v_rank_max INT;
    DECLARE v_time_start TIMESTAMP(6);
    
    DECLARE exit handler for SQLEXCEPTION
    BEGIN
        GET DIAGNOSTICS CONDITION 1
            @sqlstate = RETURNED_SQLSTATE
            , @errno = MYSQL_ERRNO
            , @text = MESSAGE_TEXT
		;
        
        ROLLBACK;
        
		CREATE TEMPORARY TABLE IF NOT EXISTS tmp_Msg_Error (
			  id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT
			, id_type INT NULL
			, code VARCHAR(250) NOT NULL
			, msg TEXT NOT NULL
		);

        INSERT INTO tmp_Msg_Error (
			  id_type
            , code
            , msg
		)
        SELECT 
			  MET.id_type
            , @errno
            , @text
		FROM parts.CORE_Msg_Error_Type MET
        WHERE MET.code = 'MYSQL_ERROR'
		;
        
        SELECT 
            t_ERROR.id_error
            , t_ERROR.id_type
            , t_ERROR.code
            , ERROR_TYPE.name
            , ERROR_TYPE.description
            , ERROR_TYPE.is_breaking_error
            , ERROR_TYPE.background_colour
            , ERROR_TYPE.text_colour
            , t_ERROR.msg
        FROM tmp_Msg_Error t_ERROR
        INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type
        ;
        
		DROP TABLE IF EXISTS tmp_Msg_Error;
    END;
    
    SET v_time_start := CURRENT_TIMESTAMP(6);
    SET v_guid := UUID();
    SET v_id_access_level_admin := (SELECT id_access_level FROM parts.DOG_Access_Level WHERE code = 'ADMIN' LIMIT 1);
    SET v_id_access_level_view := (SELECT id_access_level FROM parts.DOG_Access_Level WHERE code = 'VIEW' LIMIT 1);
    SET v_id_permission_dog_admin := (SELECT id_permission FROM parts.DOG_Permission WHERE code = 'DOG_ADMIN' LIMIT 1);
    SET v_id_permission_user := (SELECT id_permission FROM parts.DOG_Permission WHERE code = 'USER_VIEW' LIMIT 1);
    SET v_id_permission_user_admin := (SELECT id_permission FROM parts.DOG_Permission WHERE code = 'USER_ADMIN' LIMIT 1);
    SET v_code_type_error_bad_data := 'BAD_DATA';
    SET v_id_type_error_bad_data := (SELECT id_type FROM parts.CORE_Msg_Error_Type WHERE code = v_code_type_error_bad_data LIMIT 1);
    SET v_ids_permission_required := CONCAT(v_id_permission_user, ',', v_id_permission_user_admin, ',', v_id_permission_dog_admin);
    SET v_is_new := FALSE;
    
    SET a_get_all_user := IFNULL(a_get_all_user, 1);
    SET a_get_inactive_user := IFNULL(a_get_inactive_user, 0);
    SET a_ids_user := TRIM(IFNULL(a_ids_user, ''));
    SET a_auth0_ids_user := TRIM(IFNULL(a_auth0_ids_user, ''));
    SET a_names_user := TRIM(IFNULL(a_names_user, ''));
    SET a_emails_user := TRIM(IFNULL(a_emails_user, ''));
    SET a_require_all_id_search_filters_met := IFNULL(a_require_all_id_search_filters_met, 1);
    SET a_require_any_id_search_filters_met := IFNULL(a_require_any_id_search_filters_met, 1);
    SET a_require_all_non_id_search_filters_met := IFNULL(a_require_all_non_id_search_filters_met, 0);
    SET a_require_any_non_id_search_filters_met := IFNULL(a_require_any_non_id_search_filters_met, 1);
    SET a_debug := IFNULL(a_debug, 0);
    
    IF a_debug = 1 THEN
		SELECT
			a_id_user
			, a_auth0_id_user
			, a_get_all_user
			, a_get_inactive_user
			, a_ids_user
			, a_auth0_ids_user
            , a_names_user
            , a_emails_user
            , a_require_all_id_search_filters_met
            , a_require_any_id_search_filters_met
            , a_require_all_non_id_search_filters_met
            , a_require_any_non_id_search_filters_met
			, a_debug
		;
    END IF;
    
    DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error;
    DROP TEMPORARY TABLE IF EXISTS tmp_User_Access;
    DROP TEMPORARY TABLE IF EXISTS tmp_User;
    
    CREATE TEMPORARY TABLE tmp_User (
		  id_row INT PRIMARY KEY AUTO_INCREMENT NOT NULL
		, id_user INT
		, id_permission_required INT NOT NULL
		, priority_access_level_required INT NOT NULL
        , is_super_user BIT
		, priority_access_level_user INT
		, has_access BIT
		, can_view BIT
		, can_edit BIT
		, can_admin BIT
		, can_admin_dog BIT
		, can_admin_user BIT
    );
    
    CREATE TEMPORARY TABLE tmp_User_Access (
		  id_row INT PRIMARY KEY AUTO_INCREMENT NOT NULL
		, id_user INT
		, id_permission_required INT NOT NULL
		, priority_access_level_required INT NOT NULL
        , is_super_user BIT
		, priority_access_level_user INT
		, has_access BIT
		, can_view BIT
		, can_edit BIT
		, can_admin BIT
    );
    
	CREATE TEMPORARY TABLE tmp_Msg_Error (
		  id_error INT NOT NULL PRIMARY KEY AUTO_INCREMENT
		, id_type INT NOT NULL
        , code VARCHAR(250) NOT NULL
        , msg TEXT NOT NULL
	);

    -- Calculated fields
    -- Can admin dog
    IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN
        IF a_debug = 1 THEN
			SELECT 
				  v_guid -- guid
                , a_get_all_user -- get_all_user
                , a_get_inactive_user -- get_inactive_user
				, a_ids_user -- ids_user
				, a_auth0_ids_user -- a_auth0_ids_user
				, a_names_user -- a_names_user
				, a_emails_user -- a_emails_user
                , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met
                , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met
                , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met
                , a_require_any_non_id_search_filters_met -- a_require_any_non_id_search_filters_met
				, v_id_permission_dog_admin -- ids_permission
				, v_id_access_level_admin -- ids_access_level
				, 0 -- a_show_errors
				, 0 -- a_debug
			;
			SELECT * FROM parts.DOG_Calc_User_Temp;
        END IF;
        
        CALL parts.p_dog_calc_user(
              v_guid -- guid
            , a_get_all_user -- get_all_user
            , a_get_inactive_user -- get_inactive_user
            , a_ids_user -- ids_user
            , a_auth0_ids_user -- a_auth0_ids_user
            , a_names_user -- a_names_user
            , a_emails_user -- a_emails_user
            , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met
            , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met
            , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met
            , a_require_any_non_id_search_filters_met -- a_require_any_non_id_search_filters_met
            , v_id_permission_dog_admin -- ids_permission
            , v_id_access_level_admin -- ids_access_level
            , 0 -- a_show_errors
            , 0 -- a_debug
		);
        
        INSERT INTO tmp_User (
              id_user
            , id_permission_required
            , priority_access_level_required
            , is_super_user
            , priority_access_level_user
            , has_access
            , can_view
            , can_edit
            , can_admin
            , can_admin_dog
        )
        SELECT 
              CALC_USER_T.id_user
            , CALC_USER_T.id_permission_required
            , CALC_USER_T.priority_access_level_required
            , CALC_USER_T.is_super_user
            , CALC_USER_T.priority_access_level_user
            , CALC_USER_T.has_access
            , CALC_USER_T.can_view
            , CALC_USER_T.can_edit
            , CALC_USER_T.can_admin
            , CALC_USER_T.can_admin AS can_admin_dog
        FROM parts.DOG_Calc_User_Temp CALC_USER_T
        WHERE CALC_USER_T.guid = v_guid
        ;
        
        IF a_debug = 1 THEN
			SELECT * FROM tmp_User;
        END IF;
        
		CALL parts.p_dog_clear_calc_user( v_guid, FALSE );
	END IF;
    
    -- Can admin user
    IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN
        IF a_debug = 1 THEN
			SELECT 
				  v_guid -- guid
                , a_get_all_user -- get_all_user
                , a_get_inactive_user -- get_inactive_user
                , a_ids_user -- ids_user
                , a_auth0_ids_user -- a_auth0_ids_user
                , a_names_user -- a_names_user
                , a_emails_user -- a_emails_user
                , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met
                , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met
                , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met
                , a_require_any_non_id_search_filters_met -- a_require_any_non_id_search_filters_met
                , v_id_permission_user_admin -- ids_permission
                , v_id_access_level_admin -- ids_access_level
				, 0 -- a_show_errors
				, 0 -- a_debug
			;
			SELECT * FROM parts.DOG_Calc_User_Temp;
        END IF;
        
        CALL parts.p_dog_calc_user(
			  v_guid -- guid
            , a_get_all_user -- get_all_user
            , a_get_inactive_user -- get_inactive_user
            , a_ids_user -- ids_user
            , a_auth0_ids_user -- a_auth0_ids_user
            , a_names_user -- a_names_user
            , a_emails_user -- a_emails_user
            , a_require_all_id_search_filters_met -- a_require_all_id_search_filters_met
            , a_require_any_id_search_filters_met -- a_require_any_id_search_filters_met
            , a_require_all_non_id_search_filters_met -- a_require_all_non_id_search_filters_met
            , a_require_any_non_id_search_filters_met -- a_require_any_non_id_search_filters_met
            , v_id_permission_user_admin -- ids_permission
            , v_id_access_level_admin -- ids_access_level
			, 0 -- a_show_errors
            , 0 -- a_debug
		);
        
        UPDATE tmp_User t_USER
        INNER JOIN parts.DOG_Calc_User_Temp CALC_USER_T
            ON  CALC_USER_T.id_user = t_USER.id_user
            AND CALC_USER_T.guid = v_guid
        SET t_USER.can_admin_user = CALC_USER_T.can_admin
        ;
        
        IF a_debug = 1 THEN
			SELECT * FROM tmp_User;
        END IF;
        
		CALL parts.p_dog_clear_calc_user( v_guid, FALSE );
	END IF;

    -- Permissions
    IF NOT EXISTS (SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN
        IF a_debug = 1 THEN
			SELECT 
				  v_guid -- guid
                , 0 -- get_all_user
                , 0 -- get_inactive_user
				, a_id_user -- ids_user
				, a_auth0_id_user -- a_auth0_ids_user
				, '' -- a_names_user
				, '' -- a_emails_user
                , 1 -- a_require_all_id_search_filters_met
                , 1 -- a_require_any_id_search_filters_met
                , 0 -- a_require_all_non_id_search_filters_met
                , 0 -- a_require_any_non_id_search_filters_met
				, v_id_permission_user -- ids_permission
				, v_id_access_level_view -- ids_access_level
				, 0 -- a_show_errors
				, 0 -- a_debug
			;
			SELECT * FROM parts.DOG_Calc_User_Temp;
        END IF;
        
        CALL parts.p_dog_calc_user(
              v_guid -- guid
            , 0 -- get_all_user
            , 0 -- get_inactive_user
            , a_id_user -- ids_user
            , a_auth0_id_user -- a_auth0_ids_user
            , '' -- a_names_user
            , '' -- a_emails_user
            , 1 -- a_require_all_id_search_filters_met
            , 1 -- a_require_any_id_search_filters_met
            , 0 -- a_require_all_non_id_search_filters_met
            , 0 -- a_require_any_non_id_search_filters_met
            , v_id_permission_user -- ids_permission
            , v_id_access_level_view -- ids_access_level
            , 0 -- a_show_errors
            , 0 -- a_debug
		);
        
        INSERT INTO tmp_User_Access (
              id_user
            , id_permission_required
            , priority_access_level_required
            , is_super_user
            , priority_access_level_user
            , has_access
            , can_view
            , can_edit
            , can_admin
        )
        SELECT 
              CALC_USER_T.id_user
            , CALC_USER_T.id_permission_required
            , CALC_USER_T.priority_access_level_required
            , CALC_USER_T.is_super_user
            , CALC_USER_T.priority_access_level_user
            , CALC_USER_T.has_access
            , CALC_USER_T.can_view
            , CALC_USER_T.can_edit
            , CALC_USER_T.can_admin
        FROM parts.DOG_Calc_User_Temp CALC_USER_T
        WHERE CALC_USER_T.guid = v_guid
        ;

        IF a_debug = 1 THEN
			SELECT * FROM tmp_User_Access;
        END IF;
        
        IF NOT EXISTS (SELECT * FROM tmp_User_Access t_USER_ACCESS WHERE t_USER_ACCESS.has_access = 1) THEN
			INSERT INTO tmp_Msg_Error (
                  id_type
				, code
				, msg
			)
			VALUES (
                  v_id_type_error_bad_data
				, v_code_type_error_bad_data
				, CONCAT(
                      'You do not have view permissions for '
                    , (SELECT PERMISSION.name FROM parts.DOG_Permission PERMISSION WHERE PERMISSION.id_permission = v_id_permission_user LIMIT 1)
                ) 
			)
			;
        END IF;
        
		CALL parts.p_dog_clear_calc_user( v_guid, FALSE );
	END IF;
    
    
    IF EXISTS(SELECT * FROM tmp_Msg_Error t_ERROR INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type WHERE ERROR_TYPE.is_breaking_error = 1 LIMIT 1) THEN
        IF a_debug = 1 THEN
            SELECT * FROM tmp_User;
        END IF;

        DELETE FROM tmp_User;
    END IF;
    
    -- Returns
	SELECT 
		  USER.id_user
		, USER.id_user_auth0
		, USER.firstname
		, USER.surname
		, USER.email
		, USER.is_email_verified
		, USER.is_super_user
		, t_USER.can_admin_dog
		, t_USER.can_admin_user
	FROM tmp_User t_USER
	INNER JOIN parts.DOG_User USER ON t_USER.id_user = USER.id_user
	;
    
    # Errors
    SELECT 
          t_ERROR.id_error
        , t_ERROR.id_type
        , t_ERROR.code
        , ERROR_TYPE.name
        , ERROR_TYPE.description
        , ERROR_TYPE.is_breaking_error
        , ERROR_TYPE.background_colour
        , ERROR_TYPE.text_colour
        , t_ERROR.msg
    FROM tmp_Msg_Error t_ERROR
    INNER JOIN parts.CORE_Msg_Error_Type ERROR_TYPE ON t_ERROR.id_type = ERROR_TYPE.id_type
    ;
    
    IF a_debug = 1 THEN
        SELECT 'End';
		SELECT * FROM tmp_User;
		SELECT * FROM tmp_User_Access;
    END IF;
    
    -- Clean up
    DROP TEMPORARY TABLE IF EXISTS tmp_Msg_Error;
    DROP TEMPORARY TABLE IF EXISTS tmp_User_Access;
    DROP TEMPORARY TABLE IF EXISTS tmp_User;
    
    IF a_debug = 1 THEN
		CALL parts.p_debug_timing_reporting ( v_time_start );
    END IF;
END //
DELIMITER ;


/*
select * FROM parts.DOG_Calc_User_Temp;
delete FROM parts.DOG_Calc_User_Temp;

SELECT * 
FROM parts.DOG_USER;

CALL parts.p_dog_get_many_user(
	NULL -- :a_id_user, 
    , 'auth0|6582b95c895d09a70ba10fef' -- :a_auth0_id_user, 
    , 1 -- :a_get_all_user,
    , 0 --  :a_get_inactive_user,
    -- , 0 --  :a_get_first_user_only,
    , NULL --  :a_ids_user,
    , 'auth0|6582b95c895d09a70ba10fef' --  :a_auth0_ids_user
    , '' -- a_names_user
    , '' -- a_emails_user
    , 1 --  :a_require_all_id_search_filters_met,
    , 1 --  :a_require_any_id_search_filters_met,
    , 0 --  :a_require_all_non_id_search_filters_met,
    , 1 --  :a_require_any_non_id_search_filters_met,
    , 0 -- a_debug
);
*/
