create or replace procedure prc_26ai_access_control
as
   v_workspace varchar2(20) := 'AICHAT1';
   v_default_schema varchar2(20) := 'AICHAT1';
   v_app_alias varchar2(20) := '26ai Demo Hub'; 

   v_workspace_id number ; 
   v_role_id varchar2(200) := '48398609518762455:48398772342762456'; -- CUIDADO, checar em APEX_APPL_ACL_USERS apos definicao de um user manualmente
   v_error varchar2(4000);
   v_has number;
begin

/*
  Criado por: fernando.leal@oracle.com
  Data: Nov/2025
  Objetivo: agendar rotina para criacao de usuarios no APEX. 
  Em telas publicas ainda nao logadas nao é permitido usar este tipo de rotina, por isso, sera assincrona. 

  v1 - rotina para criacao de APEX user assincrono - leal


-- CUIDADO: requer JOB de banco:
-- CUIDADO: job deve estar associado ao ADMIN em funcao da permissao de criar novo usuario

BEGIN
  DBMS_SCHEDULER.create_job (
    job_name        => 'job_26ai_access_control',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'begin aichat1.prc_26ai_access_control; end;',
    start_date      => sysdate,
    repeat_interval => 'freq=secondly;',
    enabled         => TRUE);
END;

-- Pagina 9999 possui comandos de controle sobre tabela tb_26ai_access_control

*/

    -- Descobrir o ID do workspace onde está a credencial
    SELECT workspace_id 
    into v_workspace_id
    FROM apex_workspaces
    WHERE workspace = v_workspace;

   -- Ativar o contexto APEX 
   -- CUIDADO pois esta sendo executado via rotina de banco, e nao via APEX, por isso, o contexto do workspace
   apex_util.set_security_group_id(v_workspace_id);

   -- para casos com recriacao do user / reset 
   for r1 in (select * 
              from tb_26ai_access_control 
              where CREATED_STATUS = 'E' ) loop
      
      begin
         APEX_UTIL.REMOVE_USER( p_user_name => r1.USERNAME );
      exception
         when others then
        null;
      end;  
  
     APEX_UTIL.CREATE_USER(
          p_user_name            => r1.USERNAME,
          p_email_address        => lower(r1.EMAIL),
          p_web_password         => r1.INITIAL_PWD,
          p_change_password_on_first_use => 'Y',  -- cuidado
          p_default_schema       => v_default_schema
     );
               
                begin   

                    delete APEX_APPL_ACL_USERS
                    where USER_NAME_LC = lower(r1.USERNAME);

                    insert into APEX_APPL_ACL_USERS(WORKSPACE_ID,
                    	WORKSPACE,
                        WORKSPACE_DISPLAY_NAME,
                        APPLICATION_ID,
                        APPLICATION_NAME,
                        WORKING_COPY_NAME,
                        USER_NAME,
                        USER_NAME_LC,
                        ROLE_IDS,
                        ROLE_NAMES)
                    values(v_workspace_id, --:WORKSPACE_ID,
                           v_workspace,
                           v_workspace,
                           r1.app_id, --:APP_ID,   
                           v_app_alias, -- :APP_ALIAS,
                           null,
                           r1.USERNAME,
                           lower(r1.USERNAME),
                           v_role_id,
                           'Contributor, Reader');  


                /*
                ou

                -- Atribui role no app destino
                apex_acl.add_user_role(
                  p_application_id =>  r.id,
                  p_user_name      => r.user_name,
                  p_role_static_id => r.role_static_id
                );

                */ 

                exception
                   when others then
                       null;
                end;                  

                update tb_26ai_access_control
                set CREATED_STATUS = 'Y'
                where USERNAME = r1.USERNAME
                and CREATED_STATUS = 'E';  -- cuidado

   end loop;


   for r1 in (select * 
              from tb_26ai_access_control 
              where CREATED_STATUS = 'N' ) loop

        begin
      
          ---  begin
          ---      APEX_UTIL.REMOVE_USER( p_user_name => r1.USERNAME );
          --  exception
          --     when others then
          --         null;
          ---  end;     

          select count(1)
          into v_has
          from APEX_APPL_ACL_USERS
          where  USER_NAME_LC = lower(r1.USERNAME);

          if v_has = 0 then 

                APEX_UTIL.CREATE_USER(
                    p_user_name            => r1.USERNAME,
                    p_email_address        => lower(r1.EMAIL),
                    p_web_password         => r1.INITIAL_PWD,
                    p_change_password_on_first_use => 'Y',  -- cuidado
                    p_default_schema       => v_default_schema
                );
               
                begin   
                    insert into APEX_APPL_ACL_USERS(WORKSPACE_ID,
                    	WORKSPACE,
                        WORKSPACE_DISPLAY_NAME,
                        APPLICATION_ID,
                        APPLICATION_NAME,
                        WORKING_COPY_NAME,
                        USER_NAME,
                        USER_NAME_LC,
                        ROLE_IDS,
                        ROLE_NAMES)
                    values(v_workspace_id, --:WORKSPACE_ID,
                           v_workspace,
                           v_workspace,
                           r1.app_id, --:APP_ID,   
                           v_app_alias, -- :APP_ALIAS,
                           null,
                           r1.USERNAME,
                           lower(r1.USERNAME),
                           v_role_id,
                           'Contributor, Reader');  
                exception
                   when others then
                       null;
                end;                  

                update tb_26ai_access_control
                set CREATED_STATUS = 'Y'
                where USERNAME = r1.USERNAME
                and CREATED_STATUS = 'N';
                
        end if;

     exception
       when others then
          v_error := sqlerrm; 
                   
           update tb_26ai_access_control
            set CREATED_STATUS = v_error
            where USERNAME = r1.USERNAME
           and CREATED_STATUS = 'N';

      end;   

    end loop;

    commit;

end;
/