/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "cmFindProgramCommand.h"
#include "cmCacheManager.h"
#include <stdlib.h>

#if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
#endif
  
cmFindProgramCommand::cmFindProgramCommand()
{
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "FIND_XXX", "find_program");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_XXX_PATH", "CMAKE_PROGRAM_PATH");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_XXX_MAC_PATH",
                               "CMAKE_APPBUNDLE_PATH");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_SYSTEM_XXX_MAC_PATH",
                               "CMAKE_SYSTEM_APPBUNDLE_PATH");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "XXX_SYSTEM", "");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_SYSTEM_XXX_PATH", 
                               "CMAKE_SYSTEM_PROGRAM_PATH"); 
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "SEARCH_XXX_DESC", "program");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "SEARCH_XXX", "program");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "XXX_SUBDIR", "[s]bin");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_FIND_ROOT_PATH_MODE_XXX", 
                               "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");
}

// 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.c_str(), "",
                                         this->VariableDocumentation.c_str(),
                                         cmCacheManager::FILEPATH);
      }
    return true;
    }

  std::string result = FindProgram(this->Names);
  if(result != "")
    {
    // Save the value in the cache
    this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
                                       result.c_str(),
                                       this->VariableDocumentation.c_str(),
                                       cmCacheManager::FILEPATH);
    
    return true;
    }
  this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
                                 (this->VariableName + "-NOTFOUND").c_str(),
                                 this->VariableDocumentation.c_str(),
                                 cmCacheManager::FILEPATH);
  return true;
}

std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
{
  std::string program = "";

  if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)
    {
    program = FindAppBundle(names);
    }
  if(program.empty() && !this->SearchAppBundleOnly)
    {
    program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
    }

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

std::string cmFindProgramCommand
::FindAppBundle(std::vector<std::string> names)
{
  for(std::vector<std::string>::const_iterator name = names.begin();
      name != names.end() ; ++name)
    {
    
    std::string appName = *name + std::string(".app");
    std::string appPath = cmSystemTools::FindDirectory(appName.c_str(), 
                                                       this->SearchPaths, 
                                                       true);

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

  // 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);
    }

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

  return executable;
}

