#!/usr/bin/env rdmd
/+
  sdp
  sdp.d
+/
/+ sdp  sisu document parser +/
import
  std.algorithm,
  std.array,
  std.container,
  std.file,
  std.exception,
  std.json,
  // std.path,
  std.process,
  std.range,
  std.regex,
  std.stdio,
  std.string,
  std.traits,
  std.typecons,
  std.utf,
  // std.variant,
  std.conv : to;
/+ sdp  sisu document parser +/
import
  lib.sdp.compile_time_info,            // sdp/compile_time_info.d
  lib.sdp.ao_abstract_doc_source,       // sdp/ao_abstract_doc_source.d
  lib.sdp.ao_assertions,                // sdp/ao_assertions.d
  lib.sdp.ao_defaults,                  // sdp/ao_defaults.d
  lib.sdp.ao_emitter,                   // sdp/ao_emitter.d
  lib.sdp.ao_read_markup_source,        // sdp/ao_read_markup_source.d
  lib.sdp.ao_object_setter,             // sdp/ao_object_setter.d
  lib.sdp.ao_output_debugs,             // sdp/ao_output_debugs.d
  lib.sdp.ao_rgx,                       // sdp/ao_rgx.d
  lib.sdp.ao_scan_inserts,              // sdp/ao_scan_inserts.d
  lib.sdp.ao_structs,                   // sdp/ao_structs.d
  lib.sdp.ao_utils;                     // sdp/ao_utils.d
  // std.conv;
// import std.stdio;
mixin(import("version.txt"));
mixin CompileTimeInfo;
mixin RgxInit; mixin Emitters;
void main(string[] argv) {
  
  mixin SiSUheader;
  mixin SiSUbiblio;
  mixin SiSUrgxInitFlags;
  mixin SiSUmarkupRaw;
  mixin SiSUdocInserts;
  mixin SiSUdocAbstraction;
  mixin SiSUoutputDebugs;
  mixin ScreenTxtColors;
  auto cli = CLI();
  auto raw = MarkupRaw();
  auto abs = Abstraction();
  auto dbg = SDPoutputDebugs();
  // struct DocumentParts {
  //   string[string][] contents;
  //   JSONValue[string] metadata_json;
  //   JSONValue[string] make_json;
  //   string[][string][string] bookindex_unordered_hashes;
  //   JSONValue[] biblio;
  // }
  string[] fns_src;
  string flag_action;
  string[string] actions;
  actions = [
    "assert"  : "yes",
  ];
  auto rgx = Rgx();
  scope(success) {
    debug(checkdoc) {
      writefln(
        "%s~ run complete, ok ~ %s (sdp-%s.%s.%s, %s v%s, %s %s)",
        scr_txt_color["cyan"],
        scr_txt_color["off"],
        ver.major,
        ver.minor,
        ver.patch,
        __VENDOR__,
        __VERSION__,
        bits,
        os,
      );
    }
    // stderr.writeln("0");
  }
  scope(failure) {
   debug(checkdoc) {
     writefln(
       "%s~ run failure ~%s",
        scr_txt_color["fuchsia"],
        scr_txt_color["off"],
     );
   }
    // stderr.writeln("1");
  }
  scope(exit) {
    debug(checkdoc) {
      writefln(
        "(%s  v%s)",
        __VENDOR__,
        __VERSION__,
      );
    }
  }
  foreach(cmdlnins; argv) {
    if (match(cmdlnins, rgx.flag_action)) {
      flag_action ~= " " ~ cmdlnins;
      actions = cli.extract_actions(cmdlnins, actions);
    } else if (match(cmdlnins, rgx.src_pth)) {
      fns_src ~= cmdlnins;
    }
  }
  foreach(fn_src; fns_src) {
    if (!empty(fn_src)) {
      scope(success) {
        debug(checkdoc) {
          writefln(
            "%s~ document complete, ok ~%s %s",
            scr_txt_color["green"],
            scr_txt_color["off"],
            fn_src
          );
        }
        // stderr.writeln("0");
      }
      scope(failure) {
        debug(checkdoc) {
          writefln(
            "%s~ document run failure ~%s (%s  v%s)\n\t%s",
            scr_txt_color["red"],
            scr_txt_color["off"],
            __VENDOR__,
            __VERSION__,
            fn_src
          );
        }
        // stderr.writeln("1");
      }
      scope(exit) {
        debug(checkdoc) {
          writeln(
            fn_src
          );
        }
      }
      enforce(
        match(fn_src, rgx.src_pth),
        "not a sisu markup filename"
      );
      auto markup_sourcefile_content =
        raw.markupSourceContentRawLineArray(fn_src); // alternative call
        // raw.markupSourceLineArray(raw.markupSourceString(fn_src)); // alternative calls (milliseconds faster?)
      debug(insert) {
        string[string] sysenv;
        sysenv["pwd"] = shell("pwd");
        writeln(sysenv["pwd"]);
        auto m = match(fn_src, rgx.src_pth);
        // auto m = match(fn_src, rgx.src_pth);
        auto markup_src_file_path = m.captures[1];
        writefln(
          "markup source file path: %s",
          markup_src_file_path
        ); // writeln(m.captures[1]);
        writeln(m.captures[2]);
      }
      if (match(fn_src, rgx.src_fn_master)) {
      /+ if master file .ssm
        scan document source for document imports
        (inserted sub-documents)
      +/
        auto ins = Inserts();
        markup_sourcefile_content =
          ins.scan_doc_source(markup_sourcefile_content, fn_src);
      } else if (!match(fn_src, rgx.src_fn)) {
        writeln("not a recognized filename");
      }
      debug(raw) {
        foreach (line; markup_sourcefile_content) {
          writeln(line);
        }
      }
      /+ process document ao_abstract_doc_source
        SiSUdocAbstraction::Abstraction
        return abstraction as tuple
      +/
      auto t =
        abs.abstract_doc_source(markup_sourcefile_content);
      static assert(!isTypeTuple!(t));
      auto contents = t[0];
      // static assert(!isIterable!(contents));
      auto metadata_json = t[1];
      auto make_json = t[2];
      auto bookindex_unordered_hashes = t[3];
      auto biblio = t[4];
      // destroy(t);
      // DocumentParts
      debug(checkdoc) {
        dbg.abstract_doc_source_debugs(
          contents,
          make_json,
          metadata_json,
          bookindex_unordered_hashes,
          biblio,
          fn_src,
          actions
        );
      }
      // compose abstract document markup state
      // append book index
      scope(exit) {
        destroy(markup_sourcefile_content);
        destroy(t);
        destroy(contents);
        destroy(make_json);
        destroy(metadata_json);
        destroy(bookindex_unordered_hashes);
        destroy(fn_src);
        destroy(biblio);
      }
    } else {
      /+ no recognized filename provided +/
      writeln("no recognized filename");
      break;
      // terminate, stop
    }
  }
}