<commit_before>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "file_handler.h"

#include "wx/dir.h"
#include "wx/filename.h"
#include "wx/xml/xml.h"

#include "cable_unit_converter.h"
#include "cable_xml_handler.h"
#include "error_message_dialog.h"
#include "span_analyzer_app.h"
#include "span_analyzer_config_xml_handler.h"
#include "span_analyzer_data_xml_handler.h"
#include "weather_load_case_unit_converter.h"

FileHandler::FileHandler() {
}

FileHandler::~FileHandler() {
}

int FileHandler::LoadAppData(const std::string& filepath,
                             const units::UnitSystem& units,
                             SpanAnalyzerData& data) {
  std::string message = "Loading application data file: " + filepath;
  wxLogMessage(message.c_str());

  // checks if the file exists
  if (wxFileName::Exists(filepath) == false) {
    wxLogError("Application data file does not exist. Aborting.");
    return -1;
  }

  // uses an xml document to load app data file
  wxXmlDocument doc;
  if (doc.Load(filepath) == false) {
    wxLogError("Application data file contains an invalid xml structure. "
               "Aborting.");
    return -1;
  }

  // checks for valid xml root
  const wxXmlNode* root = doc.GetRoot();
  if (root->GetName() != "span_analyzer_data") {
    wxLogError("Application data file contains an invalid xml root. Aborting.");
    return root->GetLineNumber();
  }

  // gets unit system attribute from file
  wxString str_units;
  units::UnitSystem units_file;
  if (root->GetAttribute("units", &str_units) == true) {
    if (str_units == "Imperial") {
      units_file = units::UnitSystem::kImperial;
    } else if (str_units == "Metric") {
      units_file = units::UnitSystem::kMetric;
    } else {
      wxLogError("Application data file contains an invalid units attribute. "
                 "Aborting.");
      return root->GetLineNumber();
    }
  } else {
    wxLogError("Application data file is missing units attribute. Aborting.");
    return root->GetLineNumber();
  }

  // parses the xml node to populate data object
  int line_number = SpanAnalyzerDataXmlHandler::ParseNode(root, filepath,
                                                          units_file, data);
  if (line_number != 0) {
    std::string message = "Applicaton data file contains a critical error on "
                          "line " + std::to_string(line_number) + "  --  "
                          "Aborting.";
    return line_number;
  }

  // converts analysis weathercases to consistent unit style
  for (auto iter = data.weathercases_analysis.begin();
       iter != data.weathercases_analysis.end(); iter++) {
    std::list<WeatherLoadCase>& weathercases = *iter;
    for (auto it = weathercases.begin(); it != weathercases.end(); it++) {
      WeatherLoadCase& weathercase = *it;
      WeatherLoadCaseUnitConverter::ConvertUnitStyle(
          units_file,
          units::UnitStyle::kDifferent,
          units::UnitStyle::kConsistent,
          weathercase);
    }
  }

  // converts unit systems if the file doesn't match applicaton config
  if (units_file != wxGetApp().config()->units) {
    for (auto iter = data.weathercases_analysis.begin();
         iter != data.weathercases_analysis.end(); iter++) {
      std::list<WeatherLoadCase>& weathercases = *iter;
      for (auto it = weathercases.begin(); it != weathercases.end(); it++) {
        WeatherLoadCase& weathercase = *it;
        WeatherLoadCaseUnitConverter::ConvertUnitSystem(
            units_file,
            units,
            weathercase);
      }
    }
  }

  return 0;
}

int FileHandler::LoadCable(const std::string& filepath,
                           const units::UnitSystem& units,
                           Cable& cable) {
  std::string message = "Loading cable file: " + filepath;
  wxLogMessage(message.c_str());

  // checks if the file exists
  if (wxFileName::Exists(filepath) == false) {
    wxLogError("Cable file does not exist. Aborting.");
    return -1;
  }

  // uses an xml document to load cable file
  wxXmlDocument doc;
  if (doc.Load(filepath) == false) {
    wxLogError("Cable file contains an invalid xml structure. Aborting.");
    return -1;
  }

  // checks for valid xml root
  const wxXmlNode* root = doc.GetRoot();
  if (root->GetName() != "cable") {
    wxLogError("Cable file contains an invalid xml root. Aborting.");
    return root->GetLineNumber();
  }

  // gets unit system attribute from file
  wxString str_units;
  units::UnitSystem units_file;
  if (root->GetAttribute("units", &str_units) == true) {
    if (str_units == "Imperial") {
      units_file = units::UnitSystem::kImperial;
    } else if (str_units == "Metric") {
      units_file = units::UnitSystem::kMetric;
    } else {
      wxLogError("Cable file contains an invalid units attribute. Aborting.");
      return root->GetLineNumber();
    }
  } else {
    wxLogError("Cable file is missing units attribute. Aborting.");
    return root->GetLineNumber();
  }

  // parses the xml node to populate cable object
  /// \todo fix CableComponent constructor to have no default
  ///   coefficients
  cable.component_core.coefficients_polynomial_creep.clear();
  cable.component_core.coefficients_polynomial_loadstrain.clear();
  cable.component_shell.coefficients_polynomial_creep.clear();
  cable.component_shell.coefficients_polynomial_loadstrain.clear();

  int line_number = CableXmlHandler::ParseNode(root, filepath, cable);
  if (line_number != 0) {
    std::string message = "Cable file contains a critical error on line "
                          + std::to_string(line_number)
                          + ". Aborting.";
    wxLogError(message.c_str());
    return line_number;
  }

  // converts units to consistent style
  CableUnitConverter::ConvertUnitStyle(
      units_file,
      units::UnitStyle::kDifferent,
      units::UnitStyle::kConsistent,
      cable);

  // converts unit systems if the file doesn't match applicaton config
  units::UnitSystem units_config = wxGetApp().config()->units;
  if (units_file != units_config) {
    CableUnitConverter::ConvertUnitSystem(units_file, units_config, cable);
  }

  return line_number;
}

int FileHandler::LoadConfigFile(const std::string& filepath,
                                SpanAnalyzerConfig& config) {
  // checks if the file exists
  if (wxFileName::Exists(filepath) == false) {
    return -1;<commit_msg>Reworked logging output to match SpanAnalyzerDoc.<commit_after>// This is free and unencumbered software released into the public domain.
// For more information, please refer to <http://unlicense.org/>

#include "file_handler.h"

#include "wx/dir.h"
#include "wx/filename.h"
#include "wx/xml/xml.h"

#include "cable_unit_converter.h"
#include "cable_xml_handler.h"
#include "error_message_dialog.h"
#include "span_analyzer_app.h"
#include "span_analyzer_config_xml_handler.h"
#include "span_analyzer_data_xml_handler.h"
#include "weather_load_case_unit_converter.h"

FileHandler::FileHandler() {
}

FileHandler::~FileHandler() {
}

int FileHandler::LoadAppData(const std::string& filepath,
                             const units::UnitSystem& units,
                             SpanAnalyzerData& data) {
  std::string message = "Loading application data file: " + filepath;
  wxLogMessage(message.c_str());

  // checks if the file exists
  if (wxFileName::Exists(filepath) == false) {
    message = "Application data file (" + filepath + ") does not exist. "
              "Aborting.";
    wxLogError(message.c_str());
    return -1;
  }

  // uses an xml document to load app data file
  wxXmlDocument doc;
  if (doc.Load(filepath) == false) {
    message = filepath + "  --  "
              "Application data file contains an invalid xml structure. "
              "Aborting.";
    wxLogError(message.c_str());
    return -1;
  }

  // checks for valid xml root
  const wxXmlNode* root = doc.GetRoot();
  if (root->GetName() != "span_analyzer_data") {
    message = filepath + "  --  "
              "Application data file contains an invalid xml root. Aborting.";
    wxLogError(message.c_str());
    return root->GetLineNumber();
  }

  // gets unit system attribute from file
  wxString str_units;
  units::UnitSystem units_file;
  if (root->GetAttribute("units", &str_units) == true) {
    if (str_units == "Imperial") {
      units_file = units::UnitSystem::kImperial;
    } else if (str_units == "Metric") {
      units_file = units::UnitSystem::kMetric;
    } else {
      message = filepath + "  --  "
                "Application data file contains an invalid units attribute. "
                "Aborting.";
      wxLogError(message.c_str());
      return root->GetLineNumber();
    }
  } else {
    message = filepath + "  --  "
              "Application data file is missing units attribute. Aborting.";
    wxLogError(message.c_str());
    return root->GetLineNumber();
  }

  // parses the xml node to populate data object
  int line_number = SpanAnalyzerDataXmlHandler::ParseNode(root, filepath,
                                                          units_file, data);
  if (line_number != 0) {
    message = filepath + std::to_string(line_number) + "  --  "
              "Applicaton data file contains a critical parsing error. "
              "Aborting.";
    wxLogError(message.c_str());
    return line_number;
  }

  // converts analysis weathercases to consistent unit style
  for (auto iter = data.weathercases_analysis.begin();
       iter != data.weathercases_analysis.end(); iter++) {
    std::list<WeatherLoadCase>& weathercases = *iter;
    for (auto it = weathercases.begin(); it != weathercases.end(); it++) {
      WeatherLoadCase& weathercase = *it;
      WeatherLoadCaseUnitConverter::ConvertUnitStyle(
          units_file,
          units::UnitStyle::kDifferent,
          units::UnitStyle::kConsistent,
          weathercase);
    }
  }

  // converts unit systems if the file doesn't match applicaton config
  if (units_file != wxGetApp().config()->units) {
    for (auto iter = data.weathercases_analysis.begin();
         iter != data.weathercases_analysis.end(); iter++) {
      std::list<WeatherLoadCase>& weathercases = *iter;
      for (auto it = weathercases.begin(); it != weathercases.end(); it++) {
        WeatherLoadCase& weathercase = *it;
        WeatherLoadCaseUnitConverter::ConvertUnitSystem(
            units_file,
            units,
            weathercase);
      }
    }
  }

  return 0;
}

int FileHandler::LoadCable(const std::string& filepath,
                           const units::UnitSystem& units,
                           Cable& cable) {
  std::string message = "Loading cable file: " + filepath;
  wxLogMessage(message.c_str());

  // checks if the file exists
  if (wxFileName::Exists(filepath) == false) {
    message = "Cable file (" + filepath + ") does not exist. Aborting.";
    wxLogError(message.c_str());
    return -1;
  }

  // uses an xml document to load cable file
  wxXmlDocument doc;
  if (doc.Load(filepath) == false) {
    message = filepath + "  --  "
              "Cable file contains an invalid xml structure. Aborting.";
    wxLogError(message.c_str());
    return -1;
  }

  // checks for valid xml root
  const wxXmlNode* root = doc.GetRoot();
  if (root->GetName() != "cable") {
    message = filepath + "  --  "
              "Cable file contains an invalid xml root. Aborting.";
    wxLogError(message.c_str());
    return root->GetLineNumber();
  }

  // gets unit system attribute from file
  wxString str_units;
  units::UnitSystem units_file;
  if (root->GetAttribute("units", &str_units) == true) {
    if (str_units == "Imperial") {
      units_file = units::UnitSystem::kImperial;
    } else if (str_units == "Metric") {
      units_file = units::UnitSystem::kMetric;
    } else {
      message = filepath + "  --  "
                "Cable file contains an invalid units attribute. Aborting.";
      wxLogError(message.c_str());
      return root->GetLineNumber();
    }
  } else {
    message = filepath + "  --  "
              "Cable file is missing units attribute. Aborting.";
    wxLogError(message.c_str());
    return root->GetLineNumber();
  }

  // parses the xml node to populate cable object
  /// \todo fix CableComponent constructor to have no default
  ///   coefficients
  cable.component_core.coefficients_polynomial_creep.clear();
  cable.component_core.coefficients_polynomial_loadstrain.clear();
  cable.component_shell.coefficients_polynomial_creep.clear();
  cable.component_shell.coefficients_polynomial_loadstrain.clear();

  int line_number = CableXmlHandler::ParseNode(root, filepath, cable);
  if (line_number != 0) {
    message = filepath + ":" + std::to_string(line_number) + "  --  "
              "Cable file contains a critical parsing error. Aborting.";
    wxLogError(message.c_str());
    return line_number;
  }

  // converts units to consistent style
  CableUnitConverter::ConvertUnitStyle(
      units_file,
      units::UnitStyle::kDifferent,
      units::UnitStyle::kConsistent,
      cable);

  // converts unit systems if the file doesn't match applicaton config
  units::UnitSystem units_config = wxGetApp().config()->units;
  if (units_file != units_config) {
    CableUnitConverter::ConvertUnitSystem(units_file, units_config, cable);
  }

  return line_number;
}

int FileHandler::LoadConfigFile(const std::string& filepath,
                                SpanAnalyzerConfig& config) {
  // checks if the file exists
  if (wxFileName::Exists(filepath) == false) {
    return -1;
{'fraction_non_alphanumeric': 0.11897601408347393, 'fraction_numerical': 0.0011736228269639845, 'mean_word_length': 2.9121951219512194, 'pattern_counts': {'":': 1, '<': 9, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 30}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6051109', 'n_tokens_mistral': 4085, 'n_tokens_neox': 3972, 'n_words': 1013}