/**
  @file
  @brief Checks group access level for a table or library
  @details In order for a user to be able to EDIT or APPROVE a table they must
    be in a group that has been granted access to that table in the
    MPE_SECURITY table.  Alternatively, they may be in the &mpeadmins
    group (which has full access to everything).

  @param [in] base_table The base table to check for
  @param [in] user= The user for which the access level should be returned. If
    not provided, the mf_user() result is used instead.
  @param [in] access_level= (APPROVE) access_level (per MPE_SECURITY) reqd.
    Valid values:
      @li EDIT
      @li APPROVE
      @li VIEW
  @param [in] cntl_lib_var= (MPELIB) The name of a global macro variable that
    contains the libref in which the MPE_SECURITY table is stored
  @param [out] outds= (MED_ACCESSCHECK) Output WORK table containing all the
    groups for which the user is granted the particular ACCESS_LEVEL.

  <h4> SAS Macros </h4>
  @li mp_abort.sas
  @li mf_getuniquename.sas
  @li mf_getuser.sas
  @li mf_verifymacvars.sas
  @li mpe_getgroups.sas

  <h4> Related Macros </h4>
  @li mpe_accesscheck.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_accesscheck(
    base_table
    ,outds=med_accesscheck /* WORK table to contain access details */
    ,user= /* metadata user to check for */
    ,access_level=APPROVE
    ,cntl_lib_var=MPELIB
  );

  %if &user= %then %let user=%mf_getuser();

  %mp_abort(
    iftrue=(%index(&outds,.)>0 and %upcase(%scan(&outds,1,.)) ne WORK)
    ,mac=mpe_accesscheck
    ,msg=%str(outds should be a WORK table)
  )

  %mp_abort(
    iftrue=(%mf_verifymacvars(base_table user access_level)=0)
    ,mac=mpe_accesscheck
    ,msg=%str(Missing base_table/user access_level variables)
  )

  /* make unique temp table vars */
  %local tempds1 tempds2;
  %let tempds1=%mf_getuniquename(prefix=usergroups);
  %let tempds2=%mf_getuniquename(prefix=tablegroups);

  /* get list of user groups */
  %mpe_getgroups(user=&user,outds=&tempds1)

  /* get list of groups with access for that table */
  proc sql;
  create table &tempds2 as
    select distinct sas_group
    from &&&cntl_lib_var...mpe_security
    where &dc_dttmtfmt. lt tx_to
    and access_level="&access_level"
    and (
      (libref="%scan(&base_table,1,.)" and upcase(dsn)="%scan(&base_table,2,.)")
      or (libref="%scan(&base_table,1,.)" and dsn="*ALL*")
      or (libref="*ALL*")
    );
  %if &_debug ge 131 %then %do;
    data _null_;
      set &tempds1;
      putlog (_all_)(=);
    run;
    data _null_;
      set &tempds2;
      putlog (_all_)(=);
    run;
  %end;

  proc sql;
  create table &outds as
  select * from &tempds1
    where groupname="&mpeadmins"
      or groupname in (select * from &tempds2);

  %put &sysmacroname: base_table=&base_table;
  %put &sysmacroname: access_level=&access_level;
%mend mpe_accesscheck;
