/+
- Name: SisuDoc Spine, Doc Reform [a part of]
  - Description: documents, structuring, processing, publishing, search
    - static content generator

  - Author: Ralph Amissah
    [ralph.amissah@gmail.com]

  - Copyright: (C) 2015 - 2025 Ralph Amissah, All Rights Reserved.

  - License: AGPL 3 or later:

    Spine (SiSU), a framework for document structuring, publishing and
    search

    Copyright (C) Ralph Amissah

    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU AFERO General Public License as published by the
    Free Software Foundation, either version 3 of the License, or (at your
    option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    more details.

    You should have received a copy of the GNU General Public License along with
    this program. If not, see [https://www.gnu.org/licenses/].

    If you have Internet connection, the latest version of the AGPL should be
    available at these locations:
    [https://www.fsf.org/licensing/licenses/agpl.html]
    [https://www.gnu.org/licenses/agpl.html]

  - Spine (by Doc Reform, related to SiSU) uses standard:
    - docReform markup syntax
      - standard SiSU markup syntax with modified headers and minor modifications
    - docReform object numbering
      - standard SiSU object citation numbering & system

  - Homepages:
    [https://www.sisudoc.org]
    [https://www.doc-reform.org]

  - Git
    [https://git.sisudoc.org/]

+/
/++
  read configuration files<BR>
  - read config files<BR>
  meta_config_files.d
+/
module sisudoc.io_in.read_config_files;
@safe:
import
  std.file,
  std.path;
import
  sisudoc.meta,
  sisudoc.io_in.paths_source,
  sisudoc.meta.rgx_files,
  sisudoc.meta.rgx;
template readConfigSite() {
  @system final auto readConfigSite(Cf,O,Cfg)(Cf _conf_file_details, O _opt_action, Cfg _cfg) {
    mixin spineRgxIn;
    static auto rgx = RgxI();
    string conf_filename = "NONE";
    string config_file_str;
    string default_config_file_str = format(q"┃
flag:
  act0:                  "--html"
  act1:                  "--html --epub"
output:
  path:                  "%s"
default:
  language:              "en"
  papersize:             "a4"
  text_wrap:             "80"
  digest:                "sha256"
webserv:
  http:                  "%s"
  host:                  "%s"
  data_http:             "%s"
  data_host:             "%s"
  data_root_url:         "%s"
  data_root_path:        "%s"
  data_root_part:        ""
  images_root_part:      "image"
  cgi_search_form_title: "%s"
  cgi_http:              "%s"
  cgi_host:              "%s"
  cgi_bin_url:           "%s"
  cgi_bin_subpath:       "%s"
  cgi_bin_path:          "%s"
  cgi_search_script:     "%s"
  cgi_port:              ""
  cgi_user:              ""
  cgi_action:            "%s"
  db_sqlite_path:        "%s"
  db_sqlite_filename:    "%s"
  db_pg_table:           ""
  db_pg_user:            ""
┃",
  _cfg.processing_path_doc_root, // doc root
  _cfg.http_request_type,        // http
  _cfg.http_host,                // host / domain
  _cfg.http_request_type,        // data "http" or "https"
  _cfg.http_host,                // data domain "localhost"
  _cfg.www_url_doc_root,         // data root url "http://locahost" "https://sisudoc.org"
  _cfg.processing_path_doc_root, // data root path
  _cfg.cgi_search_form_title,    // cgi title // e.g. "≅ SiSU Spine search"
  _cfg.http_request_type,        // cgi http
  _cfg.http_host,                // cgi host
  _cfg.cgi_url_root,             // cgi bin url
  _cfg.cgi_bin_subpath,          // cgi bin path
  _cfg.cgi_bin_root,             // cgi bin path
  _cfg.cgi_filename,             // cgi filename
  _cfg.cgi_url_action,           // cgi action
  _cfg.db_sqlite_path,           // sqlite db path
  _cfg.db_sqlite_filename,       // sqlite db filename
);
    foreach(conf_fn; [_conf_file_details.config_filename_site]) {
      foreach(pth; _conf_file_details.possible_config_path_locations.config_local_site) {
        char[] conf_file;
        conf_filename = conf_fn;
        if (exists(pth)) {
          auto f_attrib = pth.getLinkAttributes;
          if (
            _conf_file_details.possible_config_path_locations.config_local_site.length == 1
            && f_attrib.attrIsFile
          ) {
            conf_file = pth.to!(char[]);
            conf_filename = pth.baseName;
          } else if (f_attrib.attrIsDir) {
            conf_file = ((chainPath(pth.to!string, conf_fn)).asNormalizedPath).array;
            conf_filename = conf_fn;
          }
          try {
            if (exists(conf_file)) {
              if (conf_file.getLinkAttributes.attrIsFile) {
                if (_opt_action.vox_gt1 || _opt_action.debug_do) {
                  writeln("config file used: \"", conf_file, "\" (cli flag settings override config file's individual settings)");
                }
                config_file_str = conf_file.readText;
                break;
              }
            }
          } catch (ErrnoException ex) {
          } catch (FileException ex) {
          }
        }
      }
      if (config_file_str.length > 0) { break; }
    }
    if (config_file_str.length > 0) {
      import dyaml;
      Node yaml_root;
      try {
        yaml_root = Loader.fromString(config_file_str).load();
      } catch (Throwable) {
        import std.stdio;
        writeln("ERROR failed to read config file content, not parsed as yaml, program default used");
        conf_filename = "VIRTUAL";
        config_file_str = default_config_file_str;
      }
    }
    if (config_file_str.length == 0) { /+ use dummy default config file +/
      // writeln("WARNING config file NOT found, default provided");
      conf_filename = "VIRTUAL";
      config_file_str = default_config_file_str;
    }
    struct _ConfContent {
      string filename() {
        return conf_filename;
      }
      string filetype() {
        string _ft = "";
        if (content.match(rgx.yaml_config)) {
          _ft = "yaml";
        }
        return _ft;
      }
      string content() {
        return config_file_str;
      }
    }
    return _ConfContent();
  }
}
static template readConfigDoc() {
  import
    std.file,
    std.path;
  import
    sisudoc.meta,
    sisudoc.io_in.paths_source,
    sisudoc.meta.rgx_files,
    sisudoc.meta.rgx;
  @system final auto readConfigDoc(M,E)(M _manifested, E _env) {
    mixin spineRgxIn;
    static auto rgx = RgxI();
    mixin spineRgxFiles;
    static auto rgx_files = RgxFiles();
    string config_file_str;
    string conf_filename = "NONE";
    auto _conf_file_details = configFilePaths!()(_manifested, _env);
    string[] possible_config_path_locations = _conf_file_details.possible_config_path_locations.dr_document_make;
    foreach(conf_fn; [_conf_file_details.config_filename_document]) {
      foreach(pth; possible_config_path_locations) {
        char[] conf_file = ((chainPath(pth.to!string, conf_fn)).asNormalizedPath).array;
        conf_filename = conf_fn;
        if (config_file_str.length > 0) {
          break;
        }
        try {
          if (exists(conf_file)) {
            if (conf_file.getLinkAttributes.attrIsFile) {
              config_file_str = conf_file.readText;
              break;
            }
          }
        } catch (ErrnoException ex) {
        } catch (FileException ex) {
        }
      }
      if (config_file_str.length > 0) { break; }
    }
    struct _ConfContent {
      string filename() {
        return conf_filename;
      }
      string content() {
        return config_file_str;
      }
      string filetype() {
        string _ft = "";
        if (content.match(rgx.yaml_config)) {
          _ft = "yaml";
        }
        return _ft;
      }
    }
    return _ConfContent();
  }
}
static template configReadSiteYAML() {
  import
    std.file,
    std.path;
  import
    sisudoc.meta,
    sisudoc.io_in.paths_source,
    sisudoc.meta.rgx_files,
    sisudoc.meta.rgx;
  final YAMLDocument configReadSiteYAML(M,E)(M _manifested, E _env) {
    string _configuration = configReadInSiteYAML!()(_manifested, _env);
    auto _conf_file_details = configFilePaths!()(_manifested, _env);
    string _conf_yaml_fn = _conf_file_details.config_filename_site;
    YAMLDocument _yaml_conf = configYAML!()(_configuration, _conf_yaml_fn);
    return _yaml_conf;
  }
}
static template configReadDocYAML() {
  import
    std.file,
    std.path;
  import
    sisudoc.meta,
    sisudoc.io_in.paths_source;
  final YAMLDocument configReadDocYAML(M,E)(M _manifested, E _env) {
    string _configuration = configReadInDocYAML!()(_manifested, _env);
    auto _conf_file_details = configFilePaths!()(_manifested, _env);
    string _conf_yaml_fn = _conf_file_details.config_filename_document;
    YAMLDocument _yaml_conf = configYAML!()(_configuration, _conf_yaml_fn);
    return _yaml_conf;
  }
}