*! Version 1.0, Dirk Enzmann (20-Aug-2026)
*!
*! Helper for loevh2_meta_save: (re)writes the small, self-contained
*! companion .do file that goes alongside a meta()-produced .dta file.

program define loevh2_meta_writedo

   version 16.0
   args dta do origframe origchanged

   // bt/cq/dq: literal backtick / closing-single-quote / double-quote
   // characters. ALWAYS referenced directly as bare `bt'/`cq'
   // macro references (for backtick/quote pairs) or wrapped in their
   // OWN compound double quotes `"`dq'"' (for literal double quotes)
   // inside a -file write- argument list -- NEVER pre-assembled into
   // any OTHER intermediate local macro first.
   local bt = char(96)
   local cq = char(39)
   local dq = char(34)

   // Determine local _have_svy and variables for list -- via a
   // temporary helper frame `_mfh', so the caller's own current frame
   // (whatever it may be at this point in the call chain) is never
   // disturbed by the "use ... , clear" below.
   //
   // NOTE: `origframe'/`origchanged' describe the USER's true original
   // frame/changed-status (as of before loevh2/loevh2_boot/loevh2_svy
   // was ever called) -- NOT necessarily the frame that is CURRENT
   // right now, at this point inside loevh2_meta_writedo. Only the
   // "not changed" message text uses `origchanged'; the actual
   // frame-drop-safety fix below never assumes `origframe' equals
   // c(frame) at this moment, and works correctly regardless.

   tempname _mfh
   frame create `_mfh'
   local _setvars = ""
   local _have_svy = 0
   if `origchanged' == 0 local changed = "NOT "

   // `_runlist' collects the numeric codes (run==1, run==2, ...) of
   // every run that has AT LEAST 2 rows (studies/sub-samples) -- i.e.
   // every run for which an independent, meta-native fixed/random
   // pooled summary is actually meaningful (a single-row run has
   // nothing to pool; its H/SE/N are already fully visible in the
   // "list run_id source study label H SE N ..." line above, so no
   // separate meta summarize block is generated for it -- see the
   // task discussion this feature was designed from). `_runlab`_r''
   // holds each such run's own human-readable %tc label text (read
   // back from the `run' value label already built by
   // loevh2_meta_save), for use as an on-screen header in the
   // generated .do's per-run blocks.
   local _runlist = ""
   local _ntotalruns = 0
   frame `_mfh' {
      quietly use "`dta'", clear
      capture confirm variable svy_wtype svy_wexp svy_cluster svy_strata svy_fpc
      if _rc == 0 {
         local svysetvars = "svy_wtype svy_wexp svy_cluster svy_strata svy_fpc"
         foreach v of local svysetvars {
            qui tab1 `v'
            if r(N) > 0 {
               local _setvars = "`_setvars' `v'"
               local _have_svy = 1
            }
         }
      }

      capture confirm variable run
      if _rc == 0 {
         quietly levelsof run, local(_allruns)
         local _ntotalruns : word count `_allruns'
         foreach _r of local _allruns {
            quietly count if run == `_r'
            if r(N) >= 2 {
               local _runlist = "`_runlist' `_r'"
               local _rundisp : label (run) `_r'
               local _runlab`_r' = `"`_rundisp'"'
            }
         }
      }
   }


   // Drop the temporary helper frame FIRST, then switch back to the
   // user's true original frame -- NEVER the reverse order. This
   // guarantees "frame drop `_mfh'" is never issued while `_mfh' is
   // the CURRENT frame (which is exactly what triggered "may not drop
   // current frame" in the version 1.0 code -- see the header note
   // above), regardless of what `origframe' resolves to.
   frame drop `_mfh'
   capture confirm frame `origframe'
   if _rc == 0 & "`origframe'" != "" {
      frame change `origframe'
   }
   local linesize = c(linesize)

   tempname fh
   file open `fh' using "`do'", write text replace

   file write `fh' "// Auto-generated by loevh2_meta_save -- do not edit by hand" _n
   file write `fh' "// Re-created on `c(current_date)' `c(current_time)'" _n
   file write `fh' "//" _n
   file write `fh' "// Loads `dta'" _n
   file write `fh' "// and re-runs inverse-variance (meta-analytic) pooling of the already computed" _n
   file write `fh' "// H/SE/N rows saved by loevh2/loevh2_boot/loevh2_svy's compare + meta() options." _n
   file write `fh' "//" _n
   if `_have_svy' {
      file write `fh' "// NOTE: the svy_* columns below document the survey design (weight/cluster/" _n
      file write `fh' "// strata/fpc) used to COMPUTE each loevh2_svy-sourced row's H/SE (for reference" _n
      file write `fh' "// only). This script uses ONLY the already-computed H/SE/N values below -- it" _n
      file write `fh' "// does NOT require, and cannot reconstruct, the original raw dataset(s) any row" _n
      file write `fh' "// was originally computed from." _n
   }
   else {
      file write `fh' "// This script uses ONLY the already-computed H/SE/N values below -- it does NOT" _n
      file write `fh' "// require, and cannot reconstruct, the original raw dataset(s) any row was" _n
      file write `fh' "// originally computed from." _n
   }
   file write `fh' "" _n

   file write `fh' "use " `"`dq'"' "`dta'" `"`dq'"' ", clear" _n
   file write `fh' "" _n

   file write `fh' "di as txt _n " `"`dq'"' "Sub-samples pooled from `dta':" `"`dq'"' _n
   file write `fh' "set linesize 255" _n
   file write `fh' "format H SE %6.5f" _n
   file write `fh' "list run_id source study H SE N se_type `_setvars', sepby(run_id) ab(12) noobs" _n
   file write `fh' "set linesize `linesize'" _n
   file write `fh' "" _n

   file write `fh' "// (a) Set the data up for Stata's -meta- suite reproducing the results from" _n
   file write `fh' "//     loevh2/loevh2_boot/loevh2_svy's --compare-- output (fixed-effects model," _n
   file write `fh' "//     assuming all k studies/sub-samples share exactly ONE true underlying" _n
   file write `fh' "//     effect H); further meta-analysis (set summarize, subgroup analysis, meta" _n
   file write `fh' "//     forestplot, etc.) can be run." _n
   file write `fh' "" _n
   file write `fh' "capture meta set H SE, studylab(label) eslab(Loevinger's H) fixed" _n
   file write `fh' "meta summarize, cformat(%9.4f)" _n
   file write `fh' "" _n

   file write `fh' "// (b) Set the data up for random-effects model meta analysis (assuming each" _n
   file write `fh' "//     study/sub-sample has its OWN true effect, drawn from a distribution of" _n
   file write `fh' "//     true effects -- i.e., there is genuine between-study heterogeneity," _n
   file write `fh' "//     tau^2 > 0); more commonly recommended if Q is (strongly) significant." _n
   file write `fh' "//     Further analyses (meta summarize, subgroup analyses, meta forestplot," _n
   file write `fh' "//     etc.) can be run." _n
   file write `fh' "" _n
   file write `fh' "capture meta set H SE, studylab(label) eslab(Loevinger's H) random" _n
   file write `fh' "meta summarize, cformat(%9.4f)" _n
   file write `fh' "" _n

   // (c) Per-run breakdown: written whenever (i) at least one run has 2
   // or more rows/sub-samples of its own (i.e. there is at least one
   // qualifying run for which an independent, meta-native fixed/random
   // pooled summary is actually meaningful -- see `_runlist' above), AND
   // (ii) the FILE AS A WHOLE contains 2 or more distinct runs in total
   // (`_ntotalruns', collected above alongside `_runlist' -- counting
   // EVERY run, including single-row ones, not just qualifying ones).
   local _nruns : word count `_runlist'
   if `_nruns' >= 1 & `_ntotalruns' >= 2 {
      file write `fh' "// (c) Per-run breakdown: separately pool the sub-samples contributed by EACH" _n
      file write `fh' "//     run (i.e. each separate loevh2/loevh2_boot/loevh2_svy ..., compare meta()" _n
      file write `fh' "//     call that added rows to this .dta) that has 2 or more rows of its own --" _n
      file write `fh' "//     letting you directly compare the pooled H across runs." _n
      file write `fh' "" _n
      file write `fh' "tab run" _n
      file write `fh' "" _n
      foreach _r of local _runlist {
         file write `fh' "di as txt _n " `"`dq'"' "---- `_runlab`_r'' ----" `"`dq'"' _n
         file write `fh' "capture meta set H SE if run==`_r', studylab(label) eslab(Loevinger's H) fixed" _n
         file write `fh' "meta summarize, cformat(%9.4f)" _n
         file write `fh' "" _n
         file write `fh' "capture meta set H SE if run==`_r', studylab(label) eslab(Loevinger's H) random" _n
         file write `fh' "meta summarize, cformat(%9.4f)" _n
         file write `fh' "" _n
      }
   }

   file close `fh'

   di as txt "meta(): companion pooling script written to " as res "`do'" _n _n ///
             "NOTE: " as txt "running " as res `"`do'"' as txt _n ///
             "      will replace the `changed'CHANGED dataset currently in memory with the pooled" _n ///
             "      results -- reload your own data afterward if continuing further analysis" _n ///
             "      in this Stata session."
end