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

  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 "cmFindPathCommand.h"
#include "cmCacheManager.h"

#include <cmsys/Glob.hxx>

cmFindPathCommand::cmFindPathCommand()
{
  this->EnvironmentPath = "INCLUDE";
  this->IncludeFileInPath = false;
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "FIND_XXX", "find_path");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_XXX_PATH", "CMAKE_INCLUDE_PATH");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_XXX_MAC_PATH",
                               "CMAKE_FRAMEWORK_PATH");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_SYSTEM_XXX_MAC_PATH",
                               "CMAKE_SYSTEM_FRAMEWORK_PATH");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "XXX_SYSTEM", "INCLUDE");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_SYSTEM_XXX_PATH", 
                               "CMAKE_SYSTEM_INCLUDE_PATH"); 
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "SEARCH_XXX_DESC", 
                               "directory containing the named file");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "SEARCH_XXX", "file in a directory");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "XXX_SUBDIR", "include");
  cmSystemTools::ReplaceString(this->GenericDocumentation,
                               "CMAKE_FIND_ROOT_PATH_MODE_XXX", 
                               "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");

  this->ExtraDocAdded = false;
}

const char* cmFindPathCommand::GetFullDocumentation()
{
  if(!this->ExtraDocAdded && !this->IncludeFileInPath)
    {
    this->GenericDocumentation += 
      "\n"
      "When searching for frameworks, if the file is specified as "
      "A/b.h, then the framework search will look for "
      "A.framework/Headers/b.h. "
      "If that is found the path will be set to the path to the framework. "
      "CMake will convert this to the correct -F option to include the "
      "file. ";
    this->ExtraDocAdded = true;
    }
  return this->GenericDocumentation.c_str();
}

// cmFindPathCommand
bool cmFindPathCommand
::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
{
  this->VariableDocumentation = "Path to a file.";
  this->CMakePathName = "INCLUDE";
  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(),
        (this->IncludeFileInPath ?
         cmCacheManager::FILEPATH :cmCacheManager::PATH)
        );
      }
    return true;
    }

  std::string result = this->FindHeader();
  if(result.size() != 0)
    {
    this->Makefile->AddCacheDefinition
      (this->VariableName.c_str(), result.c_str(),
       this->VariableDocumentation.c_str(),
       (this->IncludeFileInPath) ?
       cmCacheManager::FILEPATH :cmCacheManager::PATH);
    return true;
    }
  this->Makefile->AddCacheDefinition
    (this->VariableName.c_str(),
     (this->VariableName + "-NOTFOUND").c_str(),
     this->VariableDocumentation.c_str(),
     (this->IncludeFileInPath) ? 
     cmCacheManager::FILEPATH :cmCacheManager::PATH);
  return true;
}

//----------------------------------------------------------------------------
std::string cmFindPathCommand::FindHeader()
{
  std::string header;
  if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
    {
    header = this->FindFrameworkHeader();
    }
  if(header.empty() && !this->SearchFrameworkOnly)
    {
    header = this->FindNormalHeader();
    }
  if(header.empty() && this->SearchFrameworkLast)
    {
    header = this->FindFrameworkHeader();
    }
  return header;
}

std::string
cmFindPathCommand::FindHeaderInFramework(std::string const& file,
                                         std::string const& dir)
{
  cmStdString fileName = file;
  cmStdString frameWorkName;
  cmStdString::size_type pos = fileName.find("/");
  // if there is a / in the name try to find the header as a framework
  // For example bar/foo.h would look for:
  // bar.framework/Headers/foo.h
  if(pos != fileName.npos)
    {
    // remove the name from the slash;
    fileName = fileName.substr(pos+1);
    frameWorkName = file;
    frameWorkName = 
      frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
    // if the framework has a path in it then just use the filename
    if(frameWorkName.find("/") != frameWorkName.npos)
      {
      fileName = file;
      frameWorkName = "";
      } 
    if(frameWorkName.size())
      {
      std::string fpath = dir;
      fpath += frameWorkName;
      fpath += ".framework";
      std::string intPath = fpath;
      intPath += "/Headers/";
      intPath += fileName;
      if(cmSystemTools::FileExists(intPath.c_str()))
        { 
        if(this->IncludeFileInPath)
          {
          return intPath;
          }
        return fpath;
        }
      }
    }
  // if it is not found yet or not a framework header, then do a glob search
  // for all frameworks in the directory: dir/*.framework/Headers/<file>
  cmStdString glob = dir;
  glob += "*.framework/Headers/";
  glob += file;
  cmsys::Glob globIt;
  globIt.FindFiles(glob);
  std::vector<std::string> files = globIt.GetFiles();
  if(files.size())
    {
    cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
    if(this->IncludeFileInPath)
      {
      return fheader;
      }
    fheader = cmSystemTools::GetFilenamePath(fheader);
    return fheader;
    }
  return "";
}

//----------------------------------------------------------------------------
std::string cmFindPathCommand::FindNormalHeader()
{
  std::string tryPath;
  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
      ni != this->Names.end() ; ++ni)
    {
    for(std::vector<std::string>::const_iterator
          p = this->SearchPaths.begin();
        p != this->SearchPaths.end(); ++p)
      {
      tryPath = *p;
      tryPath += *ni;
      if(cmSystemTools::FileExists(tryPath.c_str()))
        {
        if(this->IncludeFileInPath)
          {
          return tryPath;
          }
        else
          {
          return *p;
          }
        }
      }
    }
  return "";
}

//----------------------------------------------------------------------------
std::string cmFindPathCommand::FindFrameworkHeader()
{
  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
      ni != this->Names.end() ; ++ni)
    {
    for(std::vector<std::string>::const_iterator
          p = this->SearchPaths.begin();
        p != this->SearchPaths.end(); ++p)
      {
      std::string fwPath = this->FindHeaderInFramework(*ni, *p);
      if(!fwPath.empty())
        {
        return fwPath;
        }
      }
    }
  return "";
}
