/++
  sdlang headers<BR>
  extract sdlang header return sdlang
+/
module sdp.ao.conf_make_meta_sdlang;
template SiSUextractSDLang() {
  import
    std.exception,
    std.regex,
    std.stdio,
    std.string,
    std.traits,
    std.typecons,
    std.utf,
    std.conv : to;
  import
    sdp.ao.defaults,
    sdp.ao.rgx;
  struct extractSDL {
    mixin SiSUregisters;
    mixin SiSUrgxInit;
    auto rgx = Rgx();
    private auto docHeaderSDLtagGet(Hs)(Hs src_header) {
      debug(asserts){
        static assert(is(typeof(src_header) == char[]));
      }
      char[][] source_header_arr =
        (cast(char[]) src_header).split(rgx.newline_eol_delimiter);
      char[] _src_header;
      foreach(header_line; source_header_arr) {
        if (!match(header_line, rgx.comments)) {
          _src_header ~= header_line ~ "\n";
        }
      }
      scope(failure) {
        stderr.writefln(
          "%s\n%s\n%s:%s failed here:\n  _src_header: %s",
          __MODULE__, __FUNCTION__,
          __FILE__, __LINE__,
          _src_header,
        );
      }
      Tag sdl_root_header;
      try {
        sdl_root_header = parseSource(_src_header.to!string);
      }
      catch(ParseException e) {
        stderr.writeln("SDLang problem with this document header:");
        stderr.writeln(_src_header);
        // Error messages of the form:
        // myFile.sdl(5:28): Error: Invalid integer suffix.
        stderr.writeln(e.msg);
      }
      debug(sdlang) {
        writeln("header SDL:");
        writeln(__LINE__, ": ",  sdl_root_header.toSDLDocument());
        writeln(__LINE__, ": ",  sdl_root_header.maybe.namespaces);
        writeln("header make sdlang: ", sdl_root_header.toSDLDocument());
        writeln(__LINE__, ": ", sdl_root_header.getTagValues("title"));
        writeln(__LINE__, ": ", sdl_root_header.getTagValues("creator"));
        Tag creator = sdl_root_header.getTag("creator");
        if (creator !is null) {
          if ("author" in creator.maybe.tags) {
            writeln(__LINE__, ": ", creator.getTagValues("author"));
          } else if ("author" in creator.maybe.attributes) {
            writeln(__LINE__, ": ", creator.maybe.attributes["author"][0].value);
          }
        }
      }
      return sdl_root_header; // sdlang.ast.Tag
    }
    private auto sdlangToAA(C,Tag)(C conf, Tag conf_sdlang) {
      debug(asserts){
        static assert(is(typeof(conf) == string[string][string]));
      }
      foreach (maintag, subtags; conf) {
        /+ writeln(__LINE__, ": ", maintag, ":- ", subtags); +/
        foreach (subtag, content; subtags) {
          if (maintag in conf_sdlang.maybe.tags) {
            Tag _maintag = conf_sdlang.getTag(maintag);
            if ((subtag in _maintag.maybe.tags)
            && (_maintag.getTagValues(subtag).length > 0)) {
              debug(headersdlang) {
                writeln(__LINE__, ": ", maintag, ":", subtag, ": ", _maintag.getTagValues(subtag)[0]);
              }
              if (_maintag.getTagValues(subtag).length == 1) {
                conf[maintag][subtag] =
                  (_maintag.getTagValues(subtag)[0]).to!string;
              } else if (_maintag.getTagValues(subtag).length > 1) {
                foreach (st; _maintag.getTagValues(subtag)) {
                  conf[maintag][subtag] ~=
                    st.to!string ~ ";";
                }
              }
            } else if ((subtag in _maintag.maybe.attributes)
            && (_maintag.maybe.attributes[subtag][0].value.length > 0)) {
              debug(headersdlang) {
                writeln(__LINE__, ": ", maintag, ":", subtag, ": ", conf_sdlang.tags[maintag][0].attributes[subtag][0].value);
              }
              conf[maintag][subtag] =
                (conf_sdlang.tags[maintag][0].attributes[subtag][0].value).to!string;
            }
          }
        }
      }
      return conf;
    }
    private auto docHeaderSDLtoAA(Ma, Tag)(Ma dochead_make, Tag header_sdlang) {
      debug(asserts){
        static assert(is(typeof(dochead_make) == string[string][string]));
      }
      dochead_make = sdlangToAA(dochead_make, header_sdlang);
      auto dochead_meta = sdlangToAA(meta_aa_empty, header_sdlang);
      if (dochead_meta["title"]["main"].empty) {
        {
          Tag _maintag = header_sdlang.getTag("title");
          if (_maintag !is null) {
            if ("main" in _maintag.maybe.tags) {
              dochead_meta["title"]["main"] =
                to!string(_maintag.getTagValues("main"));
            } else if ("main" !in _maintag.maybe.attributes) {
              writeln(__LINE__, ": ", _maintag.values[0]);
              dochead_meta["title"]["main"] =
                (_maintag.values[0]).to!string; // test that this exists
            }
          }
        }
      }
      if (!(dochead_meta["title"]["subtitle"].empty)
      && (dochead_meta["title"]["sub"].empty)) {
        dochead_meta["title"]["sub"] ~= dochead_meta["title"]["subtitle"];
      }
      dochead_meta["title"].remove("subtitle");
      if (dochead_meta["title"]["sub"].empty) {
        dochead_meta["title"]["full"] ~= dochead_meta["title"]["main"];
      } else {
        dochead_meta["title"]["full"] ~= format(
          "%s - %s",
          dochead_meta["title"]["main"],
          dochead_meta["title"]["sub"],
        );
      }
      dochead_meta["creator"]["author_raw"] = dochead_meta["creator"]["author"];
      string[] authors_arr;
      auto authors_raw_arr = dochead_meta["creator"]["author"].split(rgx.arr_delimiter);
      foreach (author_raw; authors_raw_arr) {
        authors_arr ~= author_raw.replace(rgx.raw_author_munge, "$2 $1");
      }
      dochead_meta["creator"]["author"] = join(authors_arr, ", ").chomp.chomp;
      auto t = tuple(dochead_make, dochead_meta);
      static assert(t.length==2);
      return t;
    }
  }
}