/**
  @file
  @brief Sends a changeset to staging area
  @details This is the service that is called when submitting a new edit.

  <h4> Service Inputs </h4>
  <h5> jsdata </h5>
  This is the staged data table, plus an _____DELETE__THIS__RECORD_____ column

  <h5> SASControlTable </h5>

  |ACTION:$char4.|MESSAGE:$char1.|LIBDS:$char19.|
  |---|---|---|
  |LOAD|User-Provided message|LIBREF.DATASET_NAME|

  <h4> SAS Macros </h4>
  @li mf_getuser.sas
  @li mf_nobs.sas
  @li dc_assignlib.sas
  @li mf_verifymacvars.sas
  @li mf_mkdir.sas
  @li mf_getuniquefileref.sas
  @li mpe_loader.sas
  @li mpe_filtermaster.sas
  @li mp_abort.sas
  @li mp_binarycopy.sas
  @li mp_cntlout.sas
  @li mp_ds2csv.sas
  @li mf_getplatform.sas
  @li removecolsfromwork.sas
  @li mpeinit.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.

**/

%mpeinit()

%global approver; %let approver=;
%global libref; %let libref=;
%global dsn; %let dsn=;
%global user; %let user=;
%let user=%mf_getuser();

/* load parameters */
data _null_;
  set work.sascontroltable;
  call symputx('action',action);
  /* sanitise message to prevent code injection */
  message=compress(message, '&%;');
  call symputx('message',message);
  libds=upcase(libds);
  call symputx('orig_libds',libds);
  is_fmt=0;
  if substr(cats(reverse(libds)),1,3)=:'CF-' then do;
    libds=scan(libds,1,'-');
    putlog "Format Catalog Captured";
    libds='work.fmtextract';
    call symputx('libds',libds);
    is_fmt=1;
  end;
  else call symputx('libds',libds);
  call symputx('is_fmt',is_fmt);
  putlog (_all_)(=);
run;

%mp_cntlout(
  iftrue=(&is_fmt=1)
  ,libcat=&orig_libds
  ,fmtlist=0
  ,cntlout=work.fmtextract
)

/* stream back meta info, further jquery calls will return col metadata and
  actual data */
%let libref=%upcase(%scan(&libds,1,.));
%let dsn=%upcase(%scan(&libds,2,.));
%dc_assignlib(WRITE,&libref)
%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program
  ,msg=%str(syscc=&syscc - unable to assign library &libref)
)

%mp_abort(
  iftrue=(%mf_verifymacvars(mpelocapprovals libds)=0)
  ,mac=&_program
  ,msg=%str(Missing: mpelocapprovals libds)
)

%put Verify that the upload does not violate Row Level Security checks:;
%mpe_filtermaster(ULOAD,&libds,
  dclib=&mpelib,
  outref=filtref,
  outds=work.query
)

%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program
  ,msg=%str(syscc=&syscc during filtering process)
)

/* prepare inverse query */
%let tempref=%mf_getuniquefileref();
data _null_;
  infile filtref end=eof;
  file &tempref;
  if _n_=1 then put 'where not(';
  input;
  put _infile_;
  if eof then put ')';
run;
/* apply the query */
data work.badrecords;
  set work.jsdata;
  %inc &tempref/source2;;
  putlog (_all_)(=);
run;
%mp_abort(iftrue= (%mf_nobs(work.badrecords)>0)
  ,mac=&_program
  ,msg=%str(
    Security Problem - %mf_nobs(work.badrecords) unauthorised records submitted
  )
)

PROC FORMAT;
  picture yymmddhhmmss other='%0Y%0m%0d_%0H%0M%0S' (datatype=datetime);
RUN;

/**
  * Create package folder and redirect the log
  */

/* create a dataset key (datetime plus 6 digit random number plus PID) */
%let mperef=DC%left(%sysfunc(datetime(),B8601DT19.3))_%substr(
  %sysfunc(ranuni(0)),3,6)_%substr(%str(&sysjobid    ),1,4);

/* get web url */
%global url;
%let url=localhost/SASStoredProcess;
%let platform=%mf_getplatform();
%put &=platform;
data _null_;
  length url $128;

%macro stagedata();
  %if &platform=SASVIYA %then %do;
    if symexist('_baseurl') then do;
      url=symget('_baseurl');
      if subpad(url,length(url)-9,9)='SASStudio'
        then url=substr(url,1,length(url)-11);
      else url="&systcpiphostname/SASJobExecution";
    end;
    else url="&systcpiphostname/SASJobExecution";
  %end;
  %else %if &platform=SASMETA %then %do;
    rc=METADATA_GETURI("Stored Process Web App",url);
  %end;
%mend stagedata;
%stagedata()

  call symputx('url',url);
  putlog url=;
run;

/* Create package folder */
%let dir=&mpelocapprovals/&mperef;
%mf_mkdir(&dir)

/* redirect the log */
%put; %put; %put log is being redirected;
%put to retrieve, visit this url:; %put;%put;
%let url=&url?_program=%substr(&_program
  ,1,%length(&_program)-9)getlog%str(&)table=&mperef;
%put &url;

%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program
  ,msg=%str(syscc=&syscc prior to log redirection)
)

proc printto log="&dir/weblog.txt";run;
options notes mprint;
libname approve "&dir";

/* take copy of webin file */
data _null_;
  if symexist('_WEBIN_FILEREF1') then ref=symget('_WEBIN_FILEREF1');
  else if symexist('sasjs_tables') then ref='0ref'; /* no fileref created */
  else ref='indata1';
  call symputx('ref',ref);
  putlog ref=;
run;

%mp_binarycopy(inref=&ref,outloc="&dir/_WEBIN_FILEREF1.txt",iftrue=&ref ne 0ref)


/* take copy of macvars */
data _null_;
  file "&dir/macvars.sas";
  set sashelp.vmacro;
  where scope='GLOBAL';
  put '%let ' name '=' value ';';
run;

data approve.jsdset;
  length _____DELETE__THIS__RECORD_____ $3;
  set jsdata;
run;

/**
  * mf_getvarXXX functions will fail if the target is locked - so take a copy
  * and reference that (this will also explicitly throw the lock situation)
  */
%let dscopy=work.dscopy;
data &dscopy;
  set &libds;
  stop;
run;
%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program
  ,msg=%str(Issue getting lock on &libds)
)

%mp_ds2csv(approve.jsdset
  ,dlm=COMMA
  ,outfile="&dir/&orig_libds..csv"
  ,outencoding="UTF-8"
  ,headerformat=NAME
  ,termstr=CRLF
)

%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program
  ,msg=%str(syscc=&syscc when writing the CSV)
)

%mpe_loader(mperef=&mperef
  ,submitted_reason_txt=%superq(message)
  ,approver=%quote(%trim(&approver))
  ,url=%superq(url)
  ,dc_dttmtfmt=&dc_dttmtfmt
)
%mp_abort(mode=INCLUDE)

%mp_abort(
  iftrue=(%sysfunc(fileexist(%sysfunc(pathname(work))/mf_abort.error))=1)
  ,mac=&_program..sas
  ,msg=%str(mf_abort.error=1)
)

%mp_abort(iftrue= (&syscc ne 0)
  ,mac=&_program..sas
  ,msg=%str(syscc=&syscc)
)

/* send relevant SUCCESS values */
data sasparams;
STATUS='SUCCESS';
DSID="&mperef";
url="&url";
run;

%removecolsfromwork(___TMP___MD5)

%webout(OPEN)
%webout(OBJ,sasparams)
%webout(CLOSE)

%mpeterm()
