/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmWIXSourceWriter.h"

#include "cmCPackGenerator.h"

#include "cmUuid.h"

#include <windows.h>

cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
                                     std::string const& filename,
                                     GuidType componentGuidType,
                                     RootElementType rootElementType)
  : Logger(logger)
  , File(filename.c_str())
  , State(DEFAULT)
  , SourceFilename(filename)
  , ComponentGuidType(componentGuidType)
{
  WriteXMLDeclaration();

  if (rootElementType == INCLUDE_ELEMENT_ROOT) {
    BeginElement("Include");
  } else {
    BeginElement("Wix");
  }

  AddAttribute("xmlns", "http://schemas.microsoft.com/wix/2006/wi");
}

cmWIXSourceWriter::~cmWIXSourceWriter()
{
  if (Elements.size() > 1) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  Elements.size() - 1
                    << " WiX elements were still open when closing '"
                    << SourceFilename << "'" << std::endl);
    return;
  }

  EndElement(Elements.back());
}

void cmWIXSourceWriter::BeginElement(std::string const& name)
{
  if (State == BEGIN) {
    File << ">";
  }

  File << "\n";
  Indent(Elements.size());
  File << "<" << name;

  Elements.push_back(name);
  State = BEGIN;
}

void cmWIXSourceWriter::EndElement(std::string const& name)
{
  if (Elements.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "can not end WiX element with no open elements in '"
                    << SourceFilename << "'" << std::endl);
    return;
  }

  if (Elements.back() != name) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "WiX element <"
                    << Elements.back() << "> can not be closed by </" << name
                    << "> in '" << SourceFilename << "'" << std::endl);
    return;
  }

  if (State == DEFAULT) {
    File << "\n";
    Indent(Elements.size() - 1);
    File << "</" << Elements.back() << ">";
  } else {
    File << "/>";
  }

  Elements.pop_back();
  State = DEFAULT;
}

void cmWIXSourceWriter::AddTextNode(std::string const& text)
{
  if (State == BEGIN) {
    File << ">";
  }

  if (Elements.empty()) {
    cmCPackLogger(cmCPackLog::LOG_ERROR,
                  "can not add text without open WiX element in '"
                    << SourceFilename << "'" << std::endl);
    return;
  }

  File << this->EscapeAttributeValue(text);
  State = DEFAULT;
}

void cmWIXSourceWriter::AddProcessingInstruction(std::string const& target,
                                                 std::string const& content)
{
  if (State == BEGIN) {
    File << ">";
  }

  File << "\n";
  Indent(Elements.size());
  File << "<?" << target << " " << content << "?>";

  State = DEFAULT;
}

void cmWIXSourceWriter::AddAttribute(std::string const& key,
                                     std::string const& value)
{
  File << " " << key << "=\"" << EscapeAttributeValue(value) << '"';
}

void cmWIXSourceWriter::AddAttributeUnlessEmpty(std::string const& key,
                                                std::string const& value)
{
  if (!value.empty()) {
    AddAttribute(key, value);
  }
}

std::string cmWIXSourceWriter::CreateGuidFromComponentId(
  std::string const& componentId)
{
  std::string guid = "*";
  if (this->ComponentGuidType == CMAKE_GENERATED_GUID) {
    std::string md5 = cmSystemTools::ComputeStringMD5(componentId);
    cmUuid uuid;
    std::vector<unsigned char> ns;
    guid = uuid.FromMd5(ns, md5);
  }
  return guid;
}

void cmWIXSourceWriter::WriteXMLDeclaration()
{
  File << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
}

void cmWIXSourceWriter::Indent(size_t count)
{
  for (size_t i = 0; i < count; ++i) {
    File << "    ";
  }
}

std::string cmWIXSourceWriter::EscapeAttributeValue(std::string const& value)
{
  std::string result;
  result.reserve(value.size());

  for (char c : value) {
    switch (c) {
      case '<':
        result += "&lt;";
        break;
      case '>':
        result += "&gt;";
        break;
      case '&':
        result += "&amp;";
        break;
      case '"':
        result += "&quot;";
        break;
      default:
        result += c;
        break;
    }
  }

  return result;
}
