/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <windows.h>
#include "MetadataWalker.h"
#include "XMLString.h"
#include <strsafe.h>

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace wel {

bool MetadataWalker::for_each(pugi::xml_node &node) {
  // don't shortcut resolution here so that we can log attributes.
  const std::string node_name = node.name();
  if (node_name == "Data") {
    for (pugi::xml_attribute attr : node.attributes())  {
      const auto idUpdate = [&](const std::string &input) {
        if (resolve_) {
          const auto resolved = utils::OsUtils::userIdToUsername(input);
          replaced_identifiers_[input] = resolved;
          return resolved;
        }

        replaced_identifiers_[input] = input;
        return input;
      };

      if (std::regex_match(attr.name(), regex_)) {
        updateText(node, attr.name(), idUpdate);
      }

      if (std::regex_match(attr.value(), regex_)) {
        updateText(node, attr.value(), idUpdate);
      }
    }

    if (resolve_) {
      std::string nodeText = node.text().get();
      std::vector<std::string> ids = getIdentifiers(nodeText);
      for (const auto &id : ids) {
        auto  resolved = utils::OsUtils::userIdToUsername(id);
        std::string replacement = "%{" + id + "}";
        replaced_identifiers_[id] = resolved;
        replaced_identifiers_[replacement] = resolved;
        nodeText = utils::StringUtils::replaceAll(nodeText, replacement, resolved);
      }
      node.text().set(nodeText.c_str());
    }

  }
  else if (node_name == "TimeCreated") {
    metadata_["TimeCreated"] = node.attribute("SystemTime").value();
  }
  else if (node_name == "EventRecordID") {
    metadata_["EventRecordID"] = node.text().get();
  }
  else if (node_name == "Provider") {
    metadata_["Provider"] = node.attribute("Name").value();
  }
  else if (node_name == "EventID") {
    metadata_["EventID"] = node.text().get();
  }
  else {
    static std::map<std::string, EVT_FORMAT_MESSAGE_FLAGS> formatFlagMap = { {"Channel", EvtFormatMessageChannel}, {"Keywords", EvtFormatMessageKeyword}, {"Level", EvtFormatMessageLevel}, {"Opcode", EvtFormatMessageOpcode}, {"Task",EvtFormatMessageTask} };
    auto it = formatFlagMap.find(node_name);
    if (it != formatFlagMap.end()) {
      std::function<std::string(const std::string &)> updateFunc = [&](const std::string &input) -> std::string {
        if (resolve_) {
          auto resolved = windows_event_log_metadata_.getEventData(it->second);
          if (!resolved.empty()) {
            return resolved;
          }
        }
        return input;
      };
      updateText(node, node.name(), std::move(updateFunc));
    }
    else {
      // no conversion is required here, so let the node fall through
    }
  }

  return true;
}

std::vector<std::string> MetadataWalker::getIdentifiers(const std::string &text) const {
  auto pos = text.find("%{");
  std::vector<std::string> found_strings;
  while (pos != std::string::npos) {
    auto next_pos = text.find("}", pos);
    if (next_pos != std::string::npos) {
      auto potential_identifier = text.substr(pos + 2, next_pos - (pos + 2));
      std::smatch match;
      if (potential_identifier.find("S-") != std::string::npos){
        found_strings.push_back(potential_identifier);
      }
    }
    pos = text.find("%{", pos + 2);
  }
  return found_strings;
}

std::string MetadataWalker::getMetadata(METADATA metadata) const {
    switch (metadata) {
      case LOG_NAME:
        return log_name_;
      case SOURCE:
        return getString(metadata_,"Provider");
      case TIME_CREATED:
        return windows_event_log_metadata_.getEventTimestamp();
      case EVENTID:
        return getString(metadata_,"EventID");
      case EVENT_RECORDID:
        return getString(metadata_, "EventRecordID");
      case OPCODE:
        return getString(metadata_, "Opcode");
      case TASK_CATEGORY:
        return getString(metadata_,"Task");
      case LEVEL:
        return getString(metadata_,"Level");
      case KEYWORDS:
        return getString(metadata_,"Keywords");
      case EVENT_TYPE:
        return std::to_string(windows_event_log_metadata_.getEventTypeIndex());
      case COMPUTER:
        return windows_event_log_metadata_.getComputerName();
    };
    return "N/A";
}

std::map<std::string, std::string> MetadataWalker::getFieldValues() const {
  return fields_values_;
}

std::map<std::string, std::string> MetadataWalker::getIdentifiers() const {
  return replaced_identifiers_;
}

std::string MetadataWalker::updateXmlMetadata(const std::string &xml, EVT_HANDLE metadata_ptr, EVT_HANDLE event_ptr, bool update_xml, bool resolve, const std::string &regex) {
  WindowsEventLogMetadataImpl metadata{metadata_ptr, event_ptr};
  MetadataWalker walker(metadata, "", update_xml, resolve, regex);

  pugi::xml_document doc;
  pugi::xml_parse_result result = doc.load_string(xml.c_str());

  if (result) {
    doc.traverse(walker);
    wel::XmlString writer;
    doc.print(writer, "", pugi::format_raw); // no indentation or formatting
    return writer.xml_;
  }
  else {
    throw std::runtime_error("Could not parse XML document");
  }
}

std::string MetadataWalker::to_string(const wchar_t* pChar) {
  return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(pChar);
}

void MetadataWalker::updateText(pugi::xml_node &node, const std::string &field_name, std::function<std::string(const std::string &)> &&fn) {
  std::string previous_value = node.text().get();
  auto new_field_value = fn(previous_value);
  if (new_field_value != previous_value) {
    metadata_[field_name] = new_field_value;
    if (update_xml_) {
      node.text().set(new_field_value.c_str());
    } else {
      fields_values_[field_name] = new_field_value;
    }
  }
}

} /* namespace wel */
} /* namespace minifi */
} /* namespace nifi */
} /* namespace apache */
} /* namespace org */
