/**
  @file
  @brief Post Edit Hook script for the MPE_ROW_LEVEL_SECURITY table
  @details Post edit hooks provide additional backend validation for user
  provided data.  The incoming dataset is named `work.staging_ds` and is
  provided in mpe_loader.sas.

  Available macro variables:
    @li DC_LIBREF - The DC control library
    @li LIBREF - The library of the dataset being edited (is assigned)
    @li DS - The dataset being edited

  This validation checks the incoming row_level_security settings to ensure
  each individual filter is

  It also checks that EDIT scope security is not being applied to tables
  with a REPLACE loadtype (these are incompatible - see issue #211).

  <h4> SAS Macros </h4>
  @li dc_assignlib.sas
  @li mp_abort.sas
  @li mp_filtercheck.sas

  <h4> Related Macros </h4>
  @li mpe_loader.sas

**/


/* REPLACE loadtype is incompatible with row level EDIT security (#211) */
proc sql noprint;
create table work.badloadtypes as
  select distinct cats(upcase(a.rls_libref),'.',upcase(a.rls_table)) as libds
  from work.staging_ds(where=(rls_active=1
      and upcase(rls_scope) in ('EDIT','ALL')
      and upcase(_____DELETE__THIS__RECORD_____) ne 'YES')) a
  inner join &dc_libref..mpe_tables(where=(&dc_dttmtfmt. lt tx_to)) b
    on upcase(a.rls_libref)=upcase(b.libref)
    and upcase(a.rls_table)=upcase(b.dsn)
  where upcase(b.loadtype)='REPLACE';

%let badloadtypes=0;
%let badloadtype=;
data _null_;
  set work.badloadtypes;
  call symputx('badloadtypes',_n_);
  call symputx('badloadtype',libds);
run;

%mp_abort(iftrue=(&badloadtypes ne 0)
  ,mac=mpe_row_level_security_postedit
  ,msg=%str(Row level EDIT security cannot be applied to table(s) with a%trim(
  ) REPLACE loadtype, eg: &badloadtype.  Remove the security rule(s) or%trim(
  ) change the loadtype.)
)

/* ignore scope and group for validation */
proc sql;
create table work.batches as
  select distinct upcase(rls_libref) as rls_libref,
    upcase(rls_table) as rls_table,
    rls_group_logic as group_logic,
    rls_subgroup_logic as subgroup_logic,
    rls_subgroup_id as subgroup_id,
    rls_variable_nm as variable_nm,
    rls_operator_nm as operator_nm,
    rls_raw_value as raw_value
  from work.staging_ds
  where rls_active=1
  order by rls_libref, rls_table;

%let cnt=0;
data _null_;
  set work.batches;
  by rls_libref rls_table;
  putlog (_all_)(=);
  if last.rls_table then do;
    x+1;
    call symputx(cats('libds',x),cats(rls_libref,'.',rls_table));
    call symputx('cnt',x);
  end;
run;

%macro quickloop();
%do i=1 %to &cnt;
  data work.inds&i;
    set work.batches;
    if cats(rls_libref,'.',rls_table)="&&libds&i";
    keep group_logic subgroup_logic subgroup_id variable_nm operator_nm
      raw_value;
  run;
  %dc_assignlib(READ,%scan(&&libds&i,1,.))
  %mp_filtercheck(work.inds&i
    ,targetds=&&libds&i
    ,outds=work.badrecords
    ,abort=YES
  )
%end;
%mend quickloop;

%quickloop()