/**
  @file
  @brief Testing mpe_getlabels macro
  @details Verifies that the output dataset combines:
    @li NAME from `source`
    @li LABEL / MEMLABEL from `tgt_ds`
    @li DD_SHORTDESC / DD_LONGDESC from MPE_DATADICTIONARY where DD_SOURCE
        contains the `LIB.DSN` reference and DD_TYPE='COLUMN'.

  Scenarios covered:

  1. `source` is a two-part `LIB.DSN` - labels and DD entries are
      joined directly.
  2. `source` is a WORK subset without `tgt_ds` - DD entries do not
      match.
  3. `source` is a WORK subset with `tgt_ds` set to the underlying
      `LIB.DSN` - labels come from the target and DD entries match.
  4. `source` is a WORK subset that contains only a *subset* of the
      target columns - the output contains only those columns while
      labels still come from the target.

  <h4> SAS Macros </h4>
  @li mf_getuniquename.sas
  @li mf_nobs.sas
  @li mp_assert.sas
  @li mp_assertdsobs.sas
  @li mp_assertscope.sas
  @li mpe_getlabels.sas

  @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.

**/

/* teardown - remove any seeded rows */
proc sql;
delete from &mpelib..mpe_datadictionary
  where dd_source in (
    "&mpelib..MPE_X_TEST.PRIMARY_KEY_FIELD",
    "&mpelib..MPE_X_TEST.SOME_CHAR"
  );
quit;
/* seed MPE_DATADICTIONARY with column-level entries keyed on
  LIB.DSNAME.COLUMN.  &mpelib..MPE_X_TEST is created by testsetup.sas. */
proc sql;
insert into &mpelib..mpe_datadictionary set
    tx_from=0
  ,tx_to='31DEC5999:23:59:59'dt
  ,dd_type='COLUMN'
  ,dd_source="&mpelib..MPE_X_TEST.PRIMARY_KEY_FIELD"
  ,dd_shortdesc='SHORT PK DESCRIPTION'
  ,dd_longdesc='LONG PK DESCRIPTION'
  ,dd_owner=''
  ,dd_responsible=''
  ,dd_sensitivity='';
insert into &mpelib..mpe_datadictionary set
    tx_from=0
  ,tx_to='31DEC5999:23:59:59'dt
  ,dd_type='COLUMN'
  ,dd_source="&mpelib..MPE_X_TEST.SOME_CHAR"
  ,dd_shortdesc='SHORT CHAR DESCRIPTION'
  ,dd_longdesc='LONG CHAR DESCRIPTION'
  ,dd_owner=''
  ,dd_responsible=''
  ,dd_sensitivity='';
quit;

/* Test 1 - two-part libref.dataset as source */
%mp_assertscope(SNAPSHOT)
%mpe_getlabels(COLUMNS,&mpelib..MPE_X_TEST,outds=work.test1)
%mp_assertscope(COMPARE,
  desc=Checking macro variables against previous snapshot
)

data _null_;
  set work.test1;
  putlog (_all_)(=);
run;

%mp_assertdsobs(work.test1,
  desc=Test 1 - output dataset contains rows (one per column),
  test=ATLEAST 1,
  outds=work.test_results
)

%let shortdesc_hit=0;
%let longdesc_hit=0;
data _null_;
  set work.test1;
  where upcase(name)='PRIMARY_KEY_FIELD';
  if desc='SHORT PK DESCRIPTION' then call symputx('shortdesc_hit',1);
  if longdesc='LONG PK DESCRIPTION' then call symputx('longdesc_hit',1);
run;

%mp_assert(
  iftrue=(&shortdesc_hit=1),
  desc=Test 1 - DD_SHORTDESC returned as desc,
  outds=work.test_results
)
%mp_assert(
  iftrue=(&longdesc_hit=1),
  desc=Test 1 - DD_LONGDESC returned as longdesc,
  outds=work.test_results
)

/* Test 2 - WORK subset as source, no tgt_ds.  DD_SOURCE values do not
  contain `WORK.SASDATA1`, so DD entries are not applied and desc
  falls back to whatever LABEL exists on the WORK dataset. */
data work.sasdata1;
  set &mpelib..mpe_x_test;
run;

%mpe_getlabels(COLUMNS,work.sasdata1,outds=work.test2)

data _null_;
  set work.test2;
  putlog (_all_)(=);
run;

%let shortdesc_hit2=0;
data _null_;
  set work.test2;
  where upcase(name)='PRIMARY_KEY_FIELD';
  if desc='SHORT PK DESCRIPTION' then call symputx('shortdesc_hit2',1);
run;

%mp_assert(
  iftrue=(&shortdesc_hit2=0),
  desc=Test 2 - Without tgt_ds a WORK source does not pick up DD_SHORTDESC,
  outds=work.test_results
)

/* Test 3 - WORK subset as source with tgt_ds pointing at the
  underlying LIB.DSN.  Column names are taken from the WORK subset,
  labels come from the target, DD entries are applied. */
%mpe_getlabels(COLUMNS,work.sasdata1,tgt_ds=&mpelib..MPE_X_TEST,outds=work.test3)

data _null_;
  set work.test3;
  putlog (_all_)(=);
run;

%mp_assertdsobs(work.test3,
  desc=Test 3 - output dataset contains rows,
  test=ATLEAST 1,
  outds=work.test_results
)

%let shortdesc_hit3=0;
%let longdesc_hit3=0;
data _null_;
  set work.test3;
  where upcase(name)='PRIMARY_KEY_FIELD';
  if desc='SHORT PK DESCRIPTION' then call symputx('shortdesc_hit3',1);
  if longdesc='LONG PK DESCRIPTION' then call symputx('longdesc_hit3',1);
run;

%mp_assert(
  iftrue=(&shortdesc_hit3=1),
  desc=Test 3 - DD_SHORTDESC returned as desc when tgt_ds is supplied,
  outds=work.test_results
)
%mp_assert(
  iftrue=(&longdesc_hit3=1),
  desc=Test 3 - DD_LONGDESC returned as longdesc when tgt_ds is supplied,
  outds=work.test_results
)

/* Test 4 - WORK source with a strict subset of the target columns.
  The output should contain only the columns present in `source`,
  but labels still come from `tgt_ds`. */
data work.sasdata2;
  set &mpelib..mpe_x_test (keep=primary_key_field);
run;

%mpe_getlabels(COLUMNS,work.sasdata2,tgt_ds=&mpelib..MPE_X_TEST,outds=work.test4)

data _null_;
  set work.test4;
  putlog (_all_)(=);
run;

%mp_assertdsobs(work.test4,
  desc=Test 4 - output contains exactly one row (matching the source subset),
  test=EQUALS 1,
  outds=work.test_results
)

%let shortdesc_hit4=0;
data _null_;
  set work.test4;
  where upcase(name)='PRIMARY_KEY_FIELD';
  if desc='SHORT PK DESCRIPTION' then call symputx('shortdesc_hit4',1);
run;

%mp_assert(
  iftrue=(&shortdesc_hit4=1),
  desc=Test 4 - DD_SHORTDESC returned for the retained column,
  outds=work.test_results
)


