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

#include <algorithm>
#include <cstring>
#include <utility>

#include "cmGlobalVisualStudioGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

int cmVisualStudioWCEPlatformParser::ParseVersion(const char* version)
{
  const std::string registryBase =
    cmGlobalVisualStudioGenerator::GetRegistryBase(version);
  const std::string vckey = cmStrCat(registryBase, "\\Setup\\VC;ProductDir");
  const std::string vskey = cmStrCat(registryBase, "\\Setup\\VS;ProductDir");

  if (!cmSystemTools::ReadRegistryValue(vckey, this->VcInstallDir,
                                        cmSystemTools::KeyWOW64_32) ||
      !cmSystemTools::ReadRegistryValue(vskey, this->VsInstallDir,
                                        cmSystemTools::KeyWOW64_32)) {
    return 0;
  }
  cmSystemTools::ConvertToUnixSlashes(this->VcInstallDir);
  cmSystemTools::ConvertToUnixSlashes(this->VsInstallDir);
  this->VcInstallDir.append("//");

  const std::string configFilename =
    cmStrCat(this->VcInstallDir, "vcpackages/WCE.VCPlatform.config");

  return this->ParseFile(configFilename.c_str());
}

std::string cmVisualStudioWCEPlatformParser::GetOSVersion() const
{
  if (this->OSMinorVersion.empty()) {
    return OSMajorVersion;
  }

  return cmStrCat(OSMajorVersion, '.', OSMinorVersion);
}

const char* cmVisualStudioWCEPlatformParser::GetArchitectureFamily() const
{
  auto it = this->Macros.find("ARCHFAM");
  if (it != this->Macros.end()) {
    return it->second.c_str();
  }

  return nullptr;
}

void cmVisualStudioWCEPlatformParser::StartElement(const std::string& name,
                                                   const char** attributes)
{
  if (this->FoundRequiredName) {
    return;
  }

  this->CharacterData.clear();

  if (name == "PlatformData"_s) {
    this->PlatformName.clear();
    this->OSMajorVersion.clear();
    this->OSMinorVersion.clear();
    this->Macros.clear();
  }

  if (name == "Macro"_s) {
    std::string macroName;
    std::string macroValue;

    for (const char** attr = attributes; *attr; attr += 2) {
      if (strcmp(attr[0], "Name") == 0) {
        macroName = attr[1];
      } else if (strcmp(attr[0], "Value") == 0) {
        macroValue = attr[1];
      }
    }

    if (!macroName.empty()) {
      this->Macros[macroName] = macroValue;
    }
  } else if (name == "Directories"_s) {
    for (const char** attr = attributes; *attr; attr += 2) {
      if (strcmp(attr[0], "Include") == 0) {
        this->Include = attr[1];
      } else if (strcmp(attr[0], "Library") == 0) {
        this->Library = attr[1];
      } else if (strcmp(attr[0], "Path") == 0) {
        this->Path = attr[1];
      }
    }
  }
}

void cmVisualStudioWCEPlatformParser::EndElement(const std::string& name)
{
  if (!this->RequiredName) {
    if (name == "PlatformName"_s) {
      this->AvailablePlatforms.push_back(this->CharacterData);
    }
    return;
  }

  if (this->FoundRequiredName) {
    return;
  }

  if (name == "PlatformName"_s) {
    this->PlatformName = this->CharacterData;
  } else if (name == "OSMajorVersion"_s) {
    this->OSMajorVersion = this->CharacterData;
  } else if (name == "OSMinorVersion"_s) {
    this->OSMinorVersion = this->CharacterData;
  } else if (name == "Platform"_s) {
    if (this->PlatformName == this->RequiredName) {
      this->FoundRequiredName = true;
    }
  }
}

void cmVisualStudioWCEPlatformParser::CharacterDataHandler(const char* data,
                                                           int length)
{
  this->CharacterData.append(data, length);
}

std::string cmVisualStudioWCEPlatformParser::FixPaths(
  const std::string& paths) const
{
  std::string ret = paths;
  cmSystemTools::ReplaceString(ret, "$(PATH)", "%PATH%");
  cmSystemTools::ReplaceString(ret, "$(VCInstallDir)", VcInstallDir.c_str());
  cmSystemTools::ReplaceString(ret, "$(VSInstallDir)", VsInstallDir.c_str());
  std::replace(ret.begin(), ret.end(), '\\', '/');
  cmSystemTools::ReplaceString(ret, "//", "/");
  std::replace(ret.begin(), ret.end(), '/', '\\');
  return ret;
}
