#include "InitialList.hpp"

#include <Rcpp.h>
#include <cstddef>
#include <fstream>
#include <string>
#include <utility>
#include <vector>

namespace poet {

void InitialList::initChemistry(const Rcpp::List &chem) {
  if (chem.containsElementNamed("dht_species")) {
    this->dht_species = Rcpp::as<NamedVector<uint32_t>>(chem["dht_species"]);
  }

  if (chem.containsElementNamed("pht_species")) {
    this->interp_species = Rcpp::as<NamedVector<uint32_t>>(chem["pht_species"]);
  }

  if (chem.containsElementNamed("hooks")) {
    this->chem_hooks = Rcpp::List(chem["hooks"]);

    std::vector<std::string> hook_names = this->chem_hooks.names();

    for (const auto &name : hook_names) {
      if (this->hook_name_list.find(name) == this->hook_name_list.end()) {
        Rcpp::Rcerr << "Unknown chemistry hook: " << name << std::endl;
      }
    }
  }

  if (chem.containsElementNamed("ai_surrogate_input_script")) {
    std::string ai_surrogate_input_script_path = chem["ai_surrogate_input_script"];
    ai_surrogate_input_script_path = Rcpp::as<std::string>(Rcpp::Function("normalizePath")(Rcpp::wrap(ai_surrogate_input_script_path)));
    
    // Copying the entire script for the init file 
    std::ifstream file(ai_surrogate_input_script_path);
    if (!file.is_open()) {
        // print error message and return
        Rcpp::Rcerr << "AI surrogate input script was not found at: " << ai_surrogate_input_script_path << std::endl;
    }

    std::stringstream buffer;
    buffer << file.rdbuf();
    std::string fileContent = buffer.str();
    file.close();
    
    // Get base path
    ai_surrogate_input_script_path = ai_surrogate_input_script_path.substr(0, ai_surrogate_input_script_path.find_last_of('/') + 1);
    // Add the filepath as a global variable in R to enable relative filepaths in the R script
    fileContent += "\nai_surrogate_base_path <- \"" + ai_surrogate_input_script_path + "\"";
    
    this->ai_surrogate_input_script = fileContent;
  }

  this->field_header =
      Rcpp::as<std::vector<std::string>>(this->initial_grid.names());
  this->field_header.erase(this->field_header.begin());
}

InitialList::ChemistryInit InitialList::getChemistryInit() const {
  ChemistryInit chem_init;

  chem_init.total_grid_cells = this->n_cols * this->n_rows;

  // chem_init.field_header = this->field_header;

  chem_init.database = database;
  chem_init.pqc_script = pqc_script;
  chem_init.pqc_ids = pqc_ids;
  chem_init.with_h0_o0 = with_h0_o0;
  chem_init.with_redox = with_redox;
  // chem_init.pqc_scripts = pqc_scripts;
  // chem_init.pqc_ids = pqc_ids;

  // for (std::size_t i = 0; i < pqc_ids.size(); ++i) {
  //   chem_init.pqc_input[pqc_ids[i]] = pqc_scripts[i];
  // }

  // chem_init.pqc_sol_order = pqc_solutions;

  chem_init.dht_species = dht_species;
  chem_init.interp_species = interp_species;
  chem_init.ai_surrogate_input_script = ai_surrogate_input_script;

  if (this->chem_hooks.size() > 0) {
    if (this->chem_hooks.containsElementNamed("dht_fill")) {
      chem_init.hooks.dht_fill = this->chem_hooks["dht_fill"];
    }
    if (this->chem_hooks.containsElementNamed("dht_fuzz")) {
      chem_init.hooks.dht_fuzz = this->chem_hooks["dht_fuzz"];
    }
    if (this->chem_hooks.containsElementNamed("interp_pre")) {
      chem_init.hooks.interp_pre = this->chem_hooks["interp_pre"];
    }
    if (this->chem_hooks.containsElementNamed("interp_post")) {
      chem_init.hooks.interp_post = this->chem_hooks["interp_post"];
    }
  }

  return chem_init;
}
} // namespace poet