/++
  read configuration files<BR>
  - read config files<BR>
  meta_config_files.d
+/
module sdp.output.paths_source;
import std.array,
  std.file,
  std.path,
  std.regex,
  std.stdio,
  std.conv : to;
import sdp.meta.rgx;
template PodManifest() {
  mixin SiSUrgxInit;
  static auto rgx = Rgx();
  auto PodManifest(P)(
    P   _pth = "",
  ) {
    struct ManifestFile_ {
      auto pod_manifest_filename() {
        string _manifest_file = "sisupod.manifest";
        return _manifest_file;
      }
      auto pod_manifest_path() {
        string _manifest_path;
        if (isValidPath(_pth) && _pth.isDir
        && ((_pth.chainPath(pod_manifest_filename).array).isFile)) {
          _manifest_path = _pth;
        } else if (_pth.match(rgx.src_pth_contents)
        && (_pth.isFile)) {
          _manifest_path = dirName(_pth);
        // } else { // _manifest_path = "";
        }
        return _manifest_path;
      }
      auto pod_manifest_file_with_path() {
        string _manifest_path_and_file = pod_manifest_path.chainPath(pod_manifest_filename).array;
        return _manifest_path_and_file;
      }
    }
    return ManifestFile_();
  }
}
template PodMatters() {
  mixin SiSUrgxInit;
  static auto rgx = Rgx();
  auto PodMatters(O,E,P,F)(
    O   _opt_actions,
    E   _env,
    P   _pth                   = "",
    F   _fns                   = "",
    char[][] _manifest_fn_list = [[]],
  ) {
    auto _manifest = PodManifest!()(_pth);
    struct ManifestMatters_ {
      auto pwd() {
        return _env["pwd"];
      }
      auto home() {
        return _env["home"];
      }
      auto opt_action() {
        return _opt_actions;
      }
      auto is_pod() {
        auto _is_pod = (_manifest.pod_manifest_path.length > 0) ? true : false;
        return _is_pod;
      }
      auto pod_manifest_list_of_filenames() {
        return _manifest_fn_list;
      }
      auto pod_manifest_list_of_languages() {
        string[] _lngs;
        foreach (filename_; pod_manifest_list_of_filenames) {
          string _k = "en";
          if (auto m = (filename_).match(rgx.language_code_and_filename)) {
            _k = m.captures[1].to!string;
          }
          _lngs ~= _k; // all the languages from the manifest list of filenames with paths
        }
        return _lngs;
      }
      auto pod_manifest_filename() {
        return _manifest.pod_manifest_filename;
      }
      auto pod_manifest_path() {
        return _manifest.pod_manifest_path;
      }
      auto pod_manifest_file_with_path() {
        return _manifest.pod_manifest_file_with_path;
      }
      auto pod_config_dirs() {                              // TODO
        string[] _config_dirs;
        return _config_dirs;
      }
      auto pod_image_dirs() {                               // TODO
        string[] _image_dirs;
        return _image_dirs;
      }
      auto src_fn() {
        return _fns;
      }
      auto src_lng() {
        string _k;
        if (auto m = (src_fn).match(rgx.language_code_and_filename)) {
          _k = m.captures[1];
        } else {
          _k = "en";
        }
        return _k;
      }
      auto output_path() {
        auto _output_path = pwd;
        if ((_opt_actions.output_dir_set.length > 0)
          && isValidPath(_opt_actions.output_dir_set)
        ) {
          _output_path = asNormalizedPath(_opt_actions.output_dir_set).array;
          if (!exists(_output_path)) {
            _output_path.mkdirRecurse;
          }
          assert(_output_path.isDir);
        }
        return _output_path;
      }
      auto src_config_dirs() {                              // TODO
        string[] _config_dirs;
        if (is_pod) {
        } else {
        }
        return _config_dirs;
      }
      auto src_image_dirs() {                               // TODO
        string[] _image_dirs;
        if (is_pod) {
        } else {
        }
        return _image_dirs;
      }
    }
    return ManifestMatters_();
  }
}
template ConfigFilePaths() {
  mixin SiSUrgxInit;
  static auto rgx = Rgx();
  auto ConfigFilePaths(E)(
    E   _env,
  ) {
    struct ConfFilePaths {
      auto possible_config_path_locations() {
        /+ FIX clean up conf paths ↓ +/
        string _sisudoc_conf_pwd   = chainPath(to!string(_env["pwd"]), "sisudoc/conf").array;
        string _sisudoc_conf_pwd_a = chainPath(to!string(_env["pwd"]), "conf").array;
        string _sisudoc_conf_pwd_b = chainPath(to!string(_env["pwd"]), "../conf").array;
        string _sisudoc_conf_pwd_c = chainPath(to!string(_env["pwd"]), "../../conf").array;
        string _sisudoc_conf_pwd_d = chainPath(to!string(_env["pwd"]), "../../../conf").array;
        /+ FIX clean up conf paths ↑
        (compare pwd to doc path location, and build config path)
        +/
        string _dot_pwd        = chainPath(to!string(_env["pwd"]), ".sisu").array;
        string _underscore_pwd = chainPath(to!string(_env["pwd"]), "_sisu").array;
        string _dot_home       = chainPath(to!string(_env["home"]), ".sisu").array;
        string[] _possible_config_path_locations = [
          _sisudoc_conf_pwd,
          _sisudoc_conf_pwd_a,
          _sisudoc_conf_pwd_b,
          _sisudoc_conf_pwd_c,
          _sisudoc_conf_pwd_d,
          _dot_pwd,
          _underscore_pwd,
          _dot_home,
          "/etc/sisu"
        ];
        return _possible_config_path_locations;
      }
    }
    return ConfFilePaths();
  }
}
template SiSUpathsSRC() {
  mixin SiSUrgxInit;
  static auto rgx = Rgx();
  auto SiSUpathsSRC(D,Fn)(
    D   _pwd,
    Fn  _fn_src_and_relative_path,
  ) {
    struct SisuSrcPaths {
      auto pwd() {
        return _pwd;
      }
      auto language() {
        // use command line info as well?
        string _k;
        if (auto m = _fn_src_and_relative_path.match(rgx.language_code_and_filename)) {
          _k = m.captures[1];
        } else { /+ unknown until doc_meta read, (could provide & use command line info?) +/
          _k = "xx"; // original default was "en" but is not known
        }
        return _k;
      }
      auto doc_root() {
        return "sisudoc";
      }
      auto media_root() {
        return doc_root.chainPath("media").array;
      }
      auto conf_root() {
        return doc_root.chainPath("conf").array;
      }
      auto text_root() {
        return media_root.chainPath("text").array;
      }
      auto image_root() {
        return media_root.chainPath("image").array;
      }
      auto doc_src_fn_with_path_for_text_root_and_lng() {
        return text_root.chainPath(language).array;
      }
      auto doc_src_with_relative_path() {
        return pwd.chainPath(_fn_src_and_relative_path).array;
      }
      auto doc_src_fn() {
        return _fn_src_and_relative_path.baseName.array;
      }
    }
    return SisuSrcPaths();
  }
}
template SiSUpathsSisupod() {
  mixin SiSUrgxInit;
  static auto rgx = Rgx();
  string _base_dir_pod = "sisupod";
  string _base_dir_doc = "sisudoc";
  string _suffix = ".zip";
  auto SiSUpathsSisupod()() {
    struct _PathsStruct {
      string base_filename(string fn_src) {
        auto pth = fn_src.baseName.stripExtension;
        return pth;
      }
      string sisupod_dir() {
        auto pth = _base_dir_pod;
        return pth;
      }
      string sisudoc_dir() {
        auto pth = _base_dir_doc;
        return pth;
      }
      string sisupod_filename(string fn_src) {
        string pth = _base_dir_pod.chainPath(base_filename(fn_src) ~ _suffix).array;
        return pth;
      }
      string base_filesystem(string fn_src) {
        string pth = _base_dir_pod.chainPath(base_filename(fn_src)).array;
        assert(pth == _base_dir_pod ~ "/"  ~ base_filename(fn_src),
          pth ~ " == "  ~ _base_dir_pod ~ "/" ~ base_filename(fn_src) ~ "?");
        return pth;
      }
      string base_pod(string fn_src) {
        string pth = _base_dir_pod.chainPath(base_filename(fn_src)).array; // change this
        return pth;
      }
    }
    return _PathsStruct();
  }
}

template SiSUpathsSisupods() {
  mixin SiSUrgxInit;
  static auto rgx = Rgx();
  string _base_dir_pod = "sisupod";
  string _base_dir_doc = "sisudoc";
  string _suffix = ".zip";
  auto SiSUpathsSisupods()() {
    struct _PodPaths {
      string base_filename_(string fn_src) {
        auto pth = fn_src.baseName.stripExtension;
        return pth;
      }
      string sisupod_dir_() {
        auto pth = _base_dir_pod;
        return pth;
      }
      string sisudoc_dir_() {
        auto pth = _base_dir_doc;
        return pth;
      }
      string sisupod_filename_(string fn_src) {
        string pth = _base_dir_pod.chainPath(base_filename_(fn_src) ~ _suffix).array;
        return pth;
      }
      string base_filesystem_(string fn_src) {
        string pth = _base_dir_pod.chainPath(base_filename_(fn_src)).array;
        assert(pth == _base_dir_pod ~ "/"  ~ base_filename_(fn_src),
          pth ~ " == "  ~ _base_dir_pod ~ "/" ~ base_filename_(fn_src) ~ "?");
        return pth;
      }
      string base_pod_(string fn_src) {
        string pth = _base_dir_pod.chainPath(base_filename_(fn_src)).array; // change this
        return pth;
      }
      auto base_filename(string fn_src) {
        auto pth_1_ = base_filename_(fn_src);
        auto pth_2_ = base_filename_(fn_src);
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            return pth_2_;
          }
        }
        return _pods();
      }
      auto sisupod_filename(string fn_src) {
        auto pth_1_ = sisupod_filename_(fn_src);
        auto pth_2_ = sisupod_filename_(fn_src);
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            return pth_2_;
          }
        }
        return _pods();
      }
      auto base(string fn_src) {
        auto pth_1_ = "";
        auto pth_2_ = base_filesystem_(fn_src);
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            return pth_2_;
          }
        }
        return _pods();
      }
      auto pod_root(string fn_src) {
        auto pth_1_ = "";
        auto pth_2_ = base(fn_src).filesystem_open_zpod.chainPath("").array; // "sisudoc"
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            return pth_2_;
          }
        }
        return _pods();
      }
      auto conf_root(string fn_src) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = "conf";
        auto pth_2_ = pod_root(fn_src).filesystem_open_zpod.chainPath("conf").array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto css(string fn_src) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = conf_root(fn_src).zpod.chainPath("css").array;
        auto pth_2_ = conf_root(fn_src).filesystem_open_zpod.chainPath("css").array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto media_root(string fn_src) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = "media";
        auto pth_2_ = pod_root(fn_src).filesystem_open_zpod.chainPath("media").array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto text_root(string fn_src) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = media_root(fn_src).zpod.chainPath("text").array;
        auto pth_2_ = media_root(fn_src).filesystem_open_zpod.chainPath("text").array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto doc(string fn_src) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = text_root(fn_src).zpod;
        auto pth_2_ = text_root(fn_src).filesystem_open_zpod;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto doc_lng(string fn_src, string lng) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = text_root(fn_src).zpod.chainPath(lng).array;
        auto pth_2_ = text_root(fn_src).filesystem_open_zpod.chainPath(lng).array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto image_root(string fn_src) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = media_root(fn_src).zpod.chainPath("image").array;
        auto pth_2_ = media_root(fn_src).filesystem_open_zpod.chainPath("image").array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto fn_pod_filelist(string fn_src) {
        auto pod_root_ = pod_root(fn_src);
        auto _manifest = PodManifest!()(fn_src).pod_manifest_filename;
        auto pth_1_ = _manifest;
        auto pth_2_ = pod_root(fn_src).filesystem_open_zpod.chainPath(_manifest).array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto fn_doc(string fn_src, string lng) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = doc_lng(fn_src, lng).zpod.chainPath(fn_src.baseName).array;
        auto pth_2_ = doc_lng(fn_src, lng).filesystem_open_zpod.chainPath(fn_src.baseName).array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
      auto fn_doc_insert(string fn_src, string fn_insert, string lng) {
        auto pod_root_ = pod_root(fn_src);
        auto pth_1_ = doc_lng(fn_src, lng).zpod.chainPath(fn_insert.baseName).array;
        auto pth_2_ = doc_lng(fn_src, lng).filesystem_open_zpod.chainPath(fn_insert.baseName).array;
        struct _pods {
          auto zpod() {
            return pth_1_;
          }
          auto filesystem_open_zpod() {
            assert(pod_root_.filesystem_open_zpod.chainPath(zpod).array == pth_2_);
            return pth_2_;
          }
        }
        return _pods();
      }
    }
    return _PodPaths();
  }
}