/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmFindProgramCommand.h"

#include <stdlib.h>

#if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
#endif

struct cmFindProgramHelper
{
  cmFindProgramHelper()
  {
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
    // Consider platform-specific extensions.
    this->Extensions.push_back(".com");
    this->Extensions.push_back(".exe");
#endif
    // Consider original name with no extensions.
    this->Extensions.push_back("");
  }

  // List of valid extensions.
  std::vector<std::string> Extensions;

  // Keep track of the best program file found so far.
  std::string BestPath;

  // Current names under consideration.
  std::vector<std::string> Names;

  // Current full path under consideration.
  std::string TestPath;

  void AddName(std::string const& name) { this->Names.push_back(name); }
  void SetName(std::string const& name)
  {
    this->Names.clear();
    this->AddName(name);
  }
  bool CheckDirectory(std::string const& path)
  {
    for (std::vector<std::string>::iterator i = this->Names.begin();
         i != this->Names.end(); ++i) {
      if (this->CheckDirectoryForName(path, *i)) {
        return true;
      }
    }
    return false;
  }
  bool CheckDirectoryForName(std::string const& path, std::string const& name)
  {
    for (std::vector<std::string>::iterator ext = this->Extensions.begin();
         ext != this->Extensions.end(); ++ext) {
      this->TestPath = path;
      this->TestPath += name;
      if (!ext->empty() && cmSystemTools::StringEndsWith(name, ext->c_str())) {
        continue;
      }
      this->TestPath += *ext;
      if (cmSystemTools::FileExists(this->TestPath, true)) {
        this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
        return true;
      }
    }
    return false;
  }
};

cmFindProgramCommand::cmFindProgramCommand()
{
  this->NamesPerDirAllowed = true;
}

// cmFindProgramCommand
bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn,
                                       cmExecutionStatus&)
{
  this->VariableDocumentation = "Path to a program.";
  this->CMakePathName = "PROGRAM";
  // call cmFindBase::ParseArguments
  if (!this->ParseArguments(argsIn)) {
    return false;
  }
  if (this->AlreadyInCache) {
    // If the user specifies the entry on the command line without a
    // type we should add the type and docstring but keep the original
    // value.
    if (this->AlreadyInCacheWithoutMetaInfo) {
      this->Makefile->AddCacheDefinition(this->VariableName, "",
                                         this->VariableDocumentation.c_str(),
                                         cmState::FILEPATH);
    }
    return true;
  }

  std::string result = FindProgram();
  if (result != "") {
    // Save the value in the cache
    this->Makefile->AddCacheDefinition(this->VariableName, result.c_str(),
                                       this->VariableDocumentation.c_str(),
                                       cmState::FILEPATH);

    return true;
  }
  this->Makefile->AddCacheDefinition(
    this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
    this->VariableDocumentation.c_str(), cmState::FILEPATH);
  return true;
}

std::string cmFindProgramCommand::FindProgram()
{
  std::string program = "";

  if (this->SearchAppBundleFirst || this->SearchAppBundleOnly) {
    program = FindAppBundle();
  }
  if (program.empty() && !this->SearchAppBundleOnly) {
    program = this->FindNormalProgram();
  }

  if (program.empty() && this->SearchAppBundleLast) {
    program = this->FindAppBundle();
  }
  return program;
}

std::string cmFindProgramCommand::FindNormalProgram()
{
  if (this->NamesPerDir) {
    return this->FindNormalProgramNamesPerDir();
  } else {
    return this->FindNormalProgramDirsPerName();
  }
}

std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
{
  // Search for all names in each directory.
  cmFindProgramHelper helper;
  for (std::vector<std::string>::const_iterator ni = this->Names.begin();
       ni != this->Names.end(); ++ni) {
    helper.AddName(*ni);
  }

  // Check for the names themselves (e.g. absolute paths).
  if (helper.CheckDirectory(std::string())) {
    return helper.BestPath;
  }

  // Search every directory.
  for (std::vector<std::string>::const_iterator p = this->SearchPaths.begin();
       p != this->SearchPaths.end(); ++p) {
    if (helper.CheckDirectory(*p)) {
      return helper.BestPath;
    }
  }
  // Couldn't find the program.
  return "";
}

std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
{
  // Search the entire path for each name.
  cmFindProgramHelper helper;
  for (std::vector<std::string>::const_iterator ni = this->Names.begin();
       ni != this->Names.end(); ++ni) {
    // Switch to searching for this name.
    helper.SetName(*ni);

    // Check for the name by itself (e.g. an absolute path).
    if (helper.CheckDirectory(std::string())) {
      return helper.BestPath;
    }

    // Search every directory.
    for (std::vector<std::string>::const_iterator p =
           this->SearchPaths.begin();
         p != this->SearchPaths.end(); ++p) {
      if (helper.CheckDirectory(*p)) {
        return helper.BestPath;
      }
    }
  }
  // Couldn't find the program.
  return "";
}

std::string cmFindProgramCommand::FindAppBundle()
{
  for (std::vector<std::string>::const_iterator name = this->Names.begin();
       name != this->Names.end(); ++name) {

    std::string appName = *name + std::string(".app");
    std::string appPath =
      cmSystemTools::FindDirectory(appName, this->SearchPaths, true);

    if (!appPath.empty()) {
      std::string executable = GetBundleExecutable(appPath);
      if (!executable.empty()) {
        return cmSystemTools::CollapseFullPath(executable);
      }
    }
  }

  // Couldn't find app bundle
  return "";
}

std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath)
{
  std::string executable = "";
  (void)bundlePath;
#if defined(__APPLE__)
  // Started with an example on developer.apple.com about finding bundles
  // and modified from that.

  // Get a CFString of the app bundle path
  // XXX - Is it safe to assume everything is in UTF8?
  CFStringRef bundlePathCFS = CFStringCreateWithCString(
    kCFAllocatorDefault, bundlePath.c_str(), kCFStringEncodingUTF8);

  // Make a CFURLRef from the CFString representation of the
  // bundle’s path.
  CFURLRef bundleURL = CFURLCreateWithFileSystemPath(
    kCFAllocatorDefault, bundlePathCFS, kCFURLPOSIXPathStyle, true);

  // Make a bundle instance using the URLRef.
  CFBundleRef appBundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);

  // returned executableURL is relative to <appbundle>/Contents/MacOS/
  CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle);

  if (executableURL != NULL) {
    const int MAX_OSX_PATH_SIZE = 1024;
    char buffer[MAX_OSX_PATH_SIZE];

    // Convert the CFString to a C string
    CFStringGetCString(CFURLGetString(executableURL), buffer,
                       MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8);

    // And finally to a c++ string
    executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
    // Only release CFURLRef if it's not null
    CFRelease(executableURL);
  }

  // Any CF objects returned from functions with "create" or
  // "copy" in their names must be released by us!
  CFRelease(bundlePathCFS);
  CFRelease(bundleURL);
  CFRelease(appBundle);
#endif

  return executable;
}
