/* 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 "cmGlobalVisualStudioGenerator.h"
#include "cmXMLParser.h"

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

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

  const std::string configFilename =
    this->VcInstallDir + "vcpackages/WCE.VCPlatform.config";

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

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

  return OSMajorVersion + "." + OSMinorVersion;
}

const char* cmVisualStudioWCEPlatformParser::GetArchitectureFamily() const
{
  std::map<std::string, std::string>::const_iterator it =
    this->Macros.find("ARCHFAM");
  if (it != this->Macros.end()) {
    return it->second.c_str();
  }

  return 0;
}

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

  this->CharacterData.clear();

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

  if (name == "Macro") {
    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") {
    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") {
      this->AvailablePlatforms.push_back(this->CharacterData);
    }
    return;
  }

  if (this->FoundRequiredName) {
    return;
  }

  if (name == "PlatformName") {
    this->PlatformName = this->CharacterData;
  } else if (name == "OSMajorVersion") {
    this->OSMajorVersion = this->CharacterData;
  } else if (name == "OSMinorVersion") {
    this->OSMinorVersion = this->CharacterData;
  } else if (name == "Platform") {
    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;
}
