/++
  output debugs
+/
module sdp.meta.doc_debugs;
template SiSUdebugs() {
  import
    sdp.meta.defaults,
    sdp.meta.rgx;
  import
    std.algorithm,
    std.array,
    std.container,
    std.exception,
    std.json,
    std.stdio,
    std.file,
    std.path,
    std.range,
    std.regex,
    std.string,
    std.traits,
    std.typecons,
    std.utf,
    std.conv : to;
  auto SiSUdebugs(S,T)(
    auto return ref const S  contents,
    auto return ref T        doc_matters,
  ) {
    mixin SiSUrgxInit;
    mixin InternalMarkup;
    static auto rgx = Rgx();
    auto markup = InlineMarkup();
    string key;
    debug(parent) {
      writefln(
        "%s:%s",
        __FILE__,
        __LINE__,
      );
      foreach (key; doc_matters.xml.keys_seq.seg) {
        foreach (obj; contents[key]) {
          if (obj.metainfo.is_of_part != "empty") {
            if (obj.metainfo.is_a == "heading") {
              writefln(
                "%s node: %s heading: %s %s",
                obj.object_number,
                obj.node,
                obj.heading_lev_markup,
                obj.text,
              );
            }
          }
        }
      }
    }
    debug(dumpdoc) {
      writefln(
        "> %s:%s",
        __FILE__,
        __LINE__,
      );
      if (key.length > 0) {
        foreach (obj; contents[key]) {
          if (obj.metainfo.is_of_part != "empty") {
            writefln(
              "[%s][%s]\n%s",
              obj.object_number,
              obj.metainfo.is_a,
              obj.text
            );
          }
        }
      }
    }
    debug(section_head) {
      key="head";
      if (contents[key].length > 1) {
        foreach (obj; contents[key]) {
          writefln(
            "[%s][%s]\n%s",
            obj.object_number,
            obj.metainfo.is_a,
            obj.text
          );
        }
      }
    }
    debug(section_toc) {
      key="toc_seg";
      out_toc(contents, key);
    }
    debug(section_toc_seg) {
      key="toc_seg";
      out_toc(contents, key);
    }
    debug(section_toc_scroll) {
      key="toc_scroll";
      out_toc(contents, key);
    }
    debug(segnames) {
      writeln(__LINE__);
      out_segnames(contents, doc_matters);
    }
    debug(section_body) {
      key="body";
      if (contents[key].length > 1) {
        foreach (obj; contents[key]) {
          writefln(
            "[%s][%s]\n%s",
            obj.object_number,
            obj.metainfo.is_a,
            obj.text
          );
        }
      }
    }
    debug(toc_nav_dom) {
      enum DomTags { none, open, close, close_and_open, open_still, }
      foreach (sect; doc_matters.xml.keys_seq.seg) {
        foreach (obj; contents[sect]) {
          if (obj.metainfo.is_a == "heading") {
            foreach_reverse (k; 0 .. 7) {
              switch (obj.dom_structure_markedup_tags_status[k]) {
              case DomTags.close :
                writeln(markup.indent_by_spaces_provided(k), "</", k, ">");
                break;
              case DomTags.close_and_open :
                writeln(markup.indent_by_spaces_provided(k), "</", k, ">");
                writeln(markup.indent_by_spaces_provided(k),
                  "<", k, ">", obj.text,
                  " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);
                break;
              case DomTags.open :
                writeln(markup.indent_by_spaces_provided(k),
                  "<", k, ">", obj.text,
                  " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);
                break;
              default :
                break;
              }
            }
          }
        }
      }
      writeln("--------------------");
      foreach (sect; doc_matters.xml.keys_seq.seg) {
        foreach (obj; contents[sect]) {
          if (obj.metainfo.is_a == "heading") {
            foreach_reverse (k; 0 .. 7) {
              switch (obj.dom_structure_collapsed_tags_status[k]) {
              case DomTags.close :
                writeln(markup.indent_by_spaces_provided(k), "</", k, ">");
                break;
              case DomTags.close_and_open :
                writeln(markup.indent_by_spaces_provided(k), "</", k, ">");
                writeln(markup.indent_by_spaces_provided(k),
                  "<", k, ">", obj.text,
                  " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);
                break;
              case DomTags.open :
                writeln(markup.indent_by_spaces_provided(k),
                  "<", k, ">", obj.text,
                  " file: ", obj.segment_anchor_tag, ".xhtml#", obj.ocn);
                break;
              default :
                break;
              }
            }
          }
        }
      }
    }
    debug(section_endnotes) {
      key="endnotes";
      out_endnotes(contents, key);
    }
    debug(section_endnotes_seg) {
      key="endnotes";
      out_endnotes(contents, key);
    }
    debug(section_glossary) {
      key="glossary";
      if (contents[key].length > 1) {
        foreach (obj; contents[key]) {
          writefln(
            "[%s][%s]\n%s",
            obj.object_number,
            obj.metainfo.is_a,
            obj.text
          );
        }
      }
    }
    debug(section_bibliography) {
      key="bibliography";
      if (contents[key].length > 1) {
        foreach (obj; contents[key]) {
          writefln(
            "[%s][%s]\n%s",
            obj.object_number,
            obj.metainfo.is_a,
            obj.text
          );
        }
      }
    }
    debug(section_bookindex) {
      key="bookindex_seg";
      out_bookindex(contents, key);
    }
    debug(section_bookindex_seg) {
      key="bookindex_seg";
      out_bookindex(contents, key);
    }
    debug(section_bookindex_scroll) {
      key="bookindex_scroll";
      out_bookindex(contents, key);
    }
    debug(blurb_section) {
      key="blurb";
      if (contents[key].length > 1) {
        foreach (obj; contents[key]) {
          writefln(
            "[%s][%s]\n%s",
            obj.object_number,
            obj.metainfo.is_a,
            obj.text
          );
        }
      }
    }
    debug(objects) {
      writefln(
        "> %s:%s",
        __FILE__,
        __LINE__,
      );
      foreach (obj; contents[key]) {
        if (obj.metainfo.is_of_part != "empty") {
          writefln(
            "* [%s][%s] %s",
            obj.object_number,
            obj.metainfo.is_a,
            obj.text
          );
        }
      }
    }
    debug(headermakejson) {
      writefln(
        "%s\n%s\n%s",
        "document header, metadata & make instructions:",
        doc_matters.conf_make_meta.meta,
        ptr_head_main,
      );
      foreach (main_header; ptr_head_main) {
        switch (main_header) {
        case "make":
          foreach (sub_header; ptr_head_sub_make) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        default:
          break;
        }
      }
    }
    debug(headermetadatajson) {
      writefln(
        "%s\n%s\n%s",
        "document header, metadata & make instructions:",
        doc_matters.conf_make_meta.meta,
        ptr_head_main,
      );
      foreach (main_header; ptr_head_main) {
        switch (main_header) {
        case "creator":
          foreach (sub_header; ptr_head_sub_creator) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full,
              );
            }
          }
          break;
        case "title":
          foreach (sub_header; ptr_head_sub_title) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        case "rights":
          foreach (sub_header; ptr_head_sub_rights) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        case "date":
          foreach (sub_header; ptr_head_sub_date) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        case "original":
          foreach (sub_header; ptr_head_sub_original) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        case "classify":
          foreach (sub_header; ptr_head_sub_classify) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        case "identifier":
          foreach (sub_header; ptr_head_sub_identifier) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        case "notes":
          foreach (sub_header; ptr_head_sub_notes) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        case "publisher":
          foreach (sub_header; ptr_head_sub_publisher) {
            if (doc_matters.conf_make_meta.meta.title_full.to!string.length > 2) {
              writefln(
                "%s:%s: %s",
                main_header,
                sub_header,
                doc_matters.conf_make_meta.meta.title_full
              );
            }
          }
          break;
        default:
          break;
        }
      }
    }
    debug(anchor) {
      writefln(
        "> %s:%s",
        __FILE__,
        __LINE__,
      );
      foreach (k; doc_matters.xml.keys_seq.seg) {
        foreach (obj; contents[k]) {
          if (obj.metainfo.is_a == "heading") {
            writefln(
              "%s~ [%s] %s %s",
              obj.marked_up_level,
              obj.object_number,
              obj.anchor_tags,
              // "[", obj["is"], "] ",
              obj.text
            );
          }
        }
      }
    }
    debug(heading) {                         // heading
      foreach (k; doc_matters.xml.keys_seq.seg) {
        foreach (o; contents[k]) {
          if (o.metainfo.is_a == "heading") {
            writefln(
              "%s* %s\n                (markup level: %s; collapsed level: %s)",
              replicate("  ", o.heading_lev_markup),
              strip(o.text),
              o.heading_lev_markup,
              o.heading_lev_collapsed,
            );
          }
        }
      }
    }
    debug(headings) {
      writefln(
        "> %s:%s",
        __FILE__,
        __LINE__,
      );
      foreach (k; doc_matters.xml.keys_seq.seg) {
        foreach (obj; contents[k]) {
          if (obj.metainfo.is_a == "heading") {
            writefln(
              "%s~ [%s] %s",
              obj.marked_up_level,
              obj.object_number,
              // "[", obj["is"], "] ",
              obj.text
            );
          }
        }
      }
    }
    debug(summary) {
      string[string] check = [
        "last_object_number" : "NA [debug \"checkdoc\" not run]",
      ];
    }
    debug(checkdoc) {
      if ((doc_matters.opt.action.debug_do)) {
        debug(checkdoc) {
          if (auto mfn=match(doc_matters.src.filename, rgx.src_fn)) {
            if (doc_matters.opt.action.assertions) {
              switch (mfn.captures[2]) {
              // live manual:
              case "live-manual.ssm":
                assert(check["last_object_number"] ==
                  "1019","last object_number should be: 1019 (check test, document is frequently updated)"); // ok
                break;
              // sisu_markup:
              case "sisu_markup.sst":
                assert(check["last_object_number"] ==
                  "297","last object_number expected to be: 297 rather than " ~ check["last_object_number"]); // ok
                // assert(check["last_object_number"] == "297","last object_number expected to be: 297 rather than " ~ check["last_object_number"]);
                // notes for first divergance study sisu headings 247 250
                // sisu has issue with code that contains heading 1~ which results in no object_number! ??
                // sisu currently has incorrect last body object_number of 294!
                // bug in sisu? attend
                break;
              // sisu-markup-samples:
              case "accelerando.charles_stross.sst":
                assert(check["last_object_number"] ==
                  "2861","last object_number expected to be: 2861 rather than " ~ check["last_object_number"]); // ok
                break;
              case "alices_adventures_in_wonderland.lewis_carroll.sst":
                assert(check["last_object_number"] ==
                  "805","last object_number expected to be: 805 rather than " ~ check["last_object_number"]); // 808
                break;
              case "autonomy_markup0.sst":
                assert(check["last_object_number"] ==
                  "77","last object_number expected to be: 77 rather than " ~ check["last_object_number"]); // ok endnotes
                // assert(check["last_object_number"] == "78","last object_number expected to be: 78 rather than " ~ check["last_object_number"]);
                break;
              case "content.cory_doctorow.sst":
                assert(check["last_object_number"] ==
                  "953","last object_number expected to be: 953 rather than " ~ check["last_object_number"]); // 1007 way off, check object_number off switches
                // assert(check["last_object_number"] == "953","last object_number expected to be: 953 rather than " ~ check["last_object_number"]);
                break;
              case "democratizing_innovation.eric_von_hippel.sst":
                // fixed ERROR! range violation, broken check! endnotes, bookindex, biblio
                // error in bookindex ... (ch1; ch6; ch8 )
                assert(check["last_object_number"] ==
                  "905","last object_number expected to be: 905 rather than " ~ check["last_object_number"]); // 911
                break;
              case "down_and_out_in_the_magic_kingdom.cory_doctorow.sst":
                assert(check["last_object_number"] ==
                  "1417","last object_number expected to be: 1417 rather than " ~ check["last_object_number"]); // 1455 check object_number off switches
                break;
              case "for_the_win.cory_doctorow.sst":
                assert(check["last_object_number"] ==
                  "3510","last object_number expected to be: 3510 rather than " ~ check["last_object_number"]); // 3569 check object_number off switches
                break;
              case "free_as_in_freedom_2.richard_stallman_and_the_free_software_revolution.sam_williams.richard_stallman.sst":
                assert(check["last_object_number"] ==
                  "1082","last object_number expected to be: 1082 rather than " ~ check["last_object_number"]); // check 1079 too few
                break;
              case "free_culture.lawrence_lessig.sst":
                assert(check["last_object_number"] ==
                  "1330","last object_number expected to be: 1330 rather than " ~ check["last_object_number"]); // 1312
                // fixed ERROR! range violation, broken check!
                // error in bookindex ... sections piracy (ch1) & property (ch10 market concentration) fixed
                break;
              case "free_for_all.peter_wayner.sst": // endnotes, bookindex, biblio
                assert(check["last_object_number"] ==
                  "1559","last object_number expected to be: 1559 rather than " ~ check["last_object_number"]); // 1560, check object_number off switches, has endnotes so 2 too many
                // assert(check["last_object_number"] == "1559","last object_number expected to be: 1559 rather than " ~ check["last_object_number"]);
                break;
              case "gpl2.fsf.sst":
                assert(check["last_object_number"] ==
                  "65","last object_number expected to be: 65 rather than " ~ check["last_object_number"]); // ok endnotes? check
                // assert(check["last_object_number"] == "66","last object_number expected to be: 66 rather than " ~ check["last_object_number"]);
                break;
              case "gpl3.fsf.sst":
                assert(check["last_object_number"] ==
                  "123","last object_number expected to be: 123 rather than " ~ check["last_object_number"]); // ok
                break;
              case "gullivers_travels.jonathan_swift.sst":
                assert(check["last_object_number"] ==
                  "668","last object_number expected to be: 668 rather than " ~ check["last_object_number"]); // 674
                break;
              case "little_brother.cory_doctorow.sst":
                assert(check["last_object_number"] ==
                  "3130","last object_number expected to be: 3130 rather than " ~ check["last_object_number"]); // 3204, check object_number off switches
                break;
              case "the_cathedral_and_the_bazaar.eric_s_raymond.sst":
                assert(check["last_object_number"] ==
                  "258","last object_number expected to be: 258 rather than " ~ check["last_object_number"]); // ok
                break;
              case "the_public_domain.james_boyle.sst":
                assert(check["last_object_number"] ==
                  "970","last object_number expected to be: 970 rather than " ~ check["last_object_number"]); // 978
                break;
              case "the_wealth_of_networks.yochai_benkler.sst": // endnotes, bookindex
                assert(check["last_object_number"] ==
                  "829","last object_number expected to be: 829 rather than " ~ check["last_object_number"]); // ok
                // assert(check["last_object_number"] == "832","last object_number expected to be: 832 rather than " ~ check["last_object_number"]);
                // has endnotes and bookindex, issue with sisu.rb
                break;
              case "through_the_looking_glass.lewis_carroll.sst":
                assert(check["last_object_number"] ==
                  "949","last object_number expected to be: 949 rather than " ~ check["last_object_number"]); // 955
                break;
              case "two_bits.christopher_kelty.sst": // endnotes, bookindex, biblio
                assert(check["last_object_number"] ==
                  "1190","last object_number expected to be: 1190 rather than " ~ check["last_object_number"]); // 1191
                // assert(check["last_object_number"] == "1193","last object_number expected to be: 1193 rather than " ~ check["last_object_number"]); // 1191 ok?
                // has endnotes and bookindex, issue with sisu.rb
                break;
                // fixed ERROR! range violation!
                // error in bookindex ... (ch3 the movement)
              case "un_contracts_international_sale_of_goods_convention_1980.sst":
                assert(check["last_object_number"] ==
                  "377","last object_number expected to be: 377 rather than " ~ check["last_object_number"]); // ok
                break;
              case "viral_spiral.david_bollier.sst": // endnotes, bookindex
                assert(check["last_object_number"] ==
                  "1078","last object_number expected to be: 1078 rather than " ~ check["last_object_number"]); // 1100
                // fixed ERROR! range violation!
                // error in bookindex ... (ch7 ... building the cc machine, an extra semi colon)
                break;
              default:
                writeln(doc_matters.src.filename);
                break;
              }
            }
          }
        }
        debug(checkdoc) {
          void out_segnames(S,T)(
            auto return ref const S  contents,
            auto return ref T        doc_matters,
          ) {
            foreach (key; doc_matters.xml.keys_seq.seg) {
              if (contents[key].length > 1) {
                foreach (obj; contents[key]) {
                  if (obj.heading_lev_markup == 4) {
                    writeln(obj.ptr_html_segnames, ". (", doc_matters.xml.segnames[obj.ptr_html_segnames], ") -> ",  obj.text);
                  }
                }
              }
            }
          }
        }
        debug(checkdoc) {
          void out_toc(S)(
            auto return ref const S  contents,
            string                   key,
          ) {
            if (contents[key].length > 1) {
              string indent_spaces;
              foreach (obj; contents[key]) {
                indent_spaces=markup.indent_by_spaces_provided(obj.indent_hang);
                writefln(
                  "%s%s",
                  indent_spaces,
                  obj.text
                );
              }
            }
          }
        }
        debug(checkdoc) {
          void out_endnotes(S)(
            auto return ref const S  contents,
            string                   key,
          ) {
            if (contents[key].length > 1) {
              foreach (obj; contents[key]) {
                writefln(
                  "[%s]\n%s",
                  obj.metainfo.is_a,
                  obj.text
                );
              }
            }
          }
        }
        debug(checkdoc) {
          void out_bookindex(S)(
            auto return ref const S  contents,
            string                   key,
          ) {
            if (contents[key].length > 1) {
              foreach (obj; contents[key]) {
                writefln(
                  "[%s][%s]\n%s",
                  obj.object_number,
                  obj.metainfo.is_a,
                  obj.text
                );
              }
            }
          }
        }
      }
    }
  }
}