/**
  @file
  @brief Checks if a user is able to restore a LOAD_REF
  @details Not all LOAD_REFs can be restored - maybe the user does not have
    permission, maybe the load was never loaded, or maybe the load was not
    tracked.

    The macro creates two output (global) macro variables.

  @param [in] LOAD_REF The Load Reference to check
  @param [out] outresult= (ALLOW_RESTORE) Output macro variable NAME.  Will be
    given the value of YES or NO depending on whether the user is allowed to
    restore the load ref.
  @param [out] outreason= (REASON) Output macro variable NAME.
    Will be populated with the reason for which the restore decision was made.

  <h4> SAS Macros </h4>
  @li mf_nobs.sas
  @li mf_getuser.sas
  @li mpe_accesscheck.sas
  @li mpe_getgroups.sas

  <h4> Related Macros </h4>
  @li mpe_checkrestore.test.sas

  @version 9.2
  @author 4GL Apps Ltd
  @copyright 4GL Apps Ltd.  This code may only be used within Data Controller
    and may not be re-distributed or re-sold without the express permission of
    4GL Apps Ltd.
**/

%macro mpe_checkrestore(load_ref,
  outresult=ALLOW_RESTORE,
  outreason=REASON
);

  %global &outresult &outreason;
  %let &outresult=NO;
  %let &outreason=NOTFOUND;

  %local libds;
  proc sql noprint;
  select upcase(cats(base_lib,'.',base_ds)) into: libds
    from &dc_libref..mpe_submit
    where TABLE_ID="&load_ref";

  %local base_lib base_ds;
  %let base_lib=%scan(&libds,1,.);
  %let base_ds=%scan(&libds,2,.);

  /**
    * check if there is actually a version to restore
    */
  %local audtab;
  proc sql noprint;
  select coalescec(audit_libds,"&dc_libref..MPE_AUDIT") into: audtab
  from &dc_libref..MPE_TABLES
  where &dc_dttmtfmt. lt tx_to
    and libref="%scan(&libds,1,.)" and dsn="%scan(&libds,2,.)";
  %if "&audtab"="0" %then %do;
    %let &outresult=NO;
    %let &outreason= &libds has no audit table configured;
    %return;
  %end;

  %local chk;
  %let chk=0;
  proc sql noprint;
  select count(*) into: chk from &audtab
    where load_ref="&load_ref";
  %if &chk=0 %then %do;
    %let &outresult=NO;
    %let &outreason=No entry for &load_ref in &audtab;
    %return;
  %end;

  /* grab user groups */
  %local user;
  %let user=%mf_getuser();
  %mpe_getgroups(user=&user,outds=work.groups)

  /* check if user is admin */
  %local is_admin;
  %let is_admin=0;
  proc sql;
  select count(*) into: is_admin from work.groups
    where groupname="&dc_admin_group";

  %if &is_admin>0 %then %do;
    %let &outresult=YES;
    %let &outreason=IS ADMIN;
    %return;
  %end;

  /* check if user has basic access */
  %mpe_accesscheck(&libds,outds=work.access_check
    ,user=&user
    ,access_level=EDIT
  )
  %if %mf_nobs(access_check)=0 %then %do;
    %let &outresult=NO;
    %let &outreason=No access in MPE_TABLES;
    %return;
  %end;

  /* check if user has column level security rules */
  proc sql;
  create table work.cls_rules as
    select *
    from &mpelib..mpe_column_level_security
    where &dc_dttmtfmt. lt tx_to
      and CLS_SCOPE in ("EDIT",'ALL')
      and CLS_ACTIVE=1
      and upcase(CLS_GROUP) in (select upcase(groupname) from work.groups)
      and CLS_LIBREF="%upcase(&base_lib)"
      and CLS_TABLE="%upcase(&base_ds)";
  %if %mf_nobs(work.cls_rules)>0 %then %do;
    %let &outresult=NO;
    %let &outreason=User has restrictions in MPE_COLUMN_LEVEL_SECURITY;
    data _null_;
      set work.cls_rules;
      putlog (_all_)(=);
      if _n_>5 then stop;
    run;
    %return;
  %end;

  /* check if user has row level security rules */
  proc sql;
  create table work.rls_rules as
    select *
    from &mpelib..mpe_row_level_security
    where &dc_dttmtfmt. lt tx_to
      and rls_scope in ("EDIT",'ALL')
      and upcase(rls_group) in (select upcase(groupname) from work.groups)
      and rls_libref="&base_lib"
      and rls_table="&base_ds"
      and rls_active=1;
  %if %mf_nobs(work.rls_rules)>0 %then %do;
    %let &outresult=NO;
    %let &outreason=User has restrictions in MPE_ROW_LEVEL_SECURITY;
    data _null_;
      set work.rls_rules;
      putlog (_all_)(=);
      if _n_>5 then stop;
    run;
    %return;
  %end;
  %else %do;
    %let &outresult=YES;
    %let &outreason=CHECKS PASSED;
  %end;
%mend mpe_checkrestore;
