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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmOutputRequiredFilesCommand.cxx,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:08 $
  Version:   $Revision: 1.1.1.1 $

  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 "cmOutputRequiredFilesCommand.h"
#include "cmMakeDepend.h"

class cmLBDepend : public cmMakeDepend
{
  /**
   * Compute the depend information for this class.
   */
  virtual void DependWalk(cmDependInformation* info);
};

void cmLBDepend::DependWalk(cmDependInformation* info)
{
  std::ifstream fin(info->FullPath.c_str());
  if(!fin)
    {
    cmSystemTools::Error("error can not open ", info->FullPath.c_str());
    return;
    }
  
  std::string line;
  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    if(!strncmp(line.c_str(), "#include", 8))
      {
      // if it is an include line then create a string class
      std::string currentline = line;
      size_t qstart = currentline.find('\"', 8);
      size_t qend;
      // if a quote is not found look for a <
      if(qstart == std::string::npos)
        {
        qstart = currentline.find('<', 8);
        // if a < is not found then move on
        if(qstart == std::string::npos)
          {
          cmSystemTools::Error("unknown include directive ", 
                               currentline.c_str() );
          continue;
          }
        else
          {
          qend = currentline.find('>', qstart+1);
          }
        }
      else
        {
        qend = currentline.find('\"', qstart+1);
        }
      // extract the file being included
      std::string includeFile = currentline.substr(qstart+1, qend - qstart-1);
      // see if the include matches the regular expression
      if(!this->IncludeFileRegularExpression.find(includeFile))
        {
        if(this->Verbose)
          {
          std::string message = "Skipping ";
          message += includeFile;
          message += " for file ";
          message += info->FullPath.c_str();
          cmSystemTools::Error(message.c_str(), 0);
          }
        continue;
        }
      
      // Add this file and all its dependencies.
      this->AddDependency(info, includeFile.c_str());
      /// add the cxx file if it exists
      std::string cxxFile = includeFile;
      std::string::size_type pos = cxxFile.rfind('.');
      if(pos != std::string::npos)
        {
        std::string root = cxxFile.substr(0, pos);
        cxxFile = root + ".cxx";
        bool found = false;
        // try jumping to .cxx .cpp and .c in order
        if(cmSystemTools::FileExists(cxxFile.c_str()))
          {
          found = true;
          }
        for(std::vector<std::string>::iterator i = 
              this->IncludeDirectories.begin();
            i != this->IncludeDirectories.end(); ++i)
          {
          std::string path = *i;
          path = path + "/";
          path = path + cxxFile;
          if(cmSystemTools::FileExists(path.c_str()))
            {
            found = true;
            }
          }
        if (!found)
          {
          cxxFile = root + ".cpp";
          if(cmSystemTools::FileExists(cxxFile.c_str()))
            {
            found = true;
            }
          for(std::vector<std::string>::iterator i = 
                this->IncludeDirectories.begin();
              i != this->IncludeDirectories.end(); ++i)
            {
            std::string path = *i;
            path = path + "/";
            path = path + cxxFile;
            if(cmSystemTools::FileExists(path.c_str()))
              {
              found = true;
              }
            }
          }
        if (!found)
          {
          cxxFile = root + ".c";
          if(cmSystemTools::FileExists(cxxFile.c_str()))
            {
            found = true;
            }
          for(std::vector<std::string>::iterator i = 
                this->IncludeDirectories.begin();
              i != this->IncludeDirectories.end(); ++i)
            {
            std::string path = *i;
            path = path + "/";
            path = path + cxxFile;
            if(cmSystemTools::FileExists(path.c_str()))
              {
              found = true;
              }
            }
          }
        if (!found)
          {
          cxxFile = root + ".txx";
          if(cmSystemTools::FileExists(cxxFile.c_str()))
            {
            found = true;
            }
          for(std::vector<std::string>::iterator i = 
                this->IncludeDirectories.begin();
              i != this->IncludeDirectories.end(); ++i)
            {
            std::string path = *i;
            path = path + "/";
            path = path + cxxFile;
            if(cmSystemTools::FileExists(path.c_str()))
              {
              found = true;
              }
            }
          }
        if (found)
          {
          this->AddDependency(info, cxxFile.c_str());
          }
        }
      }
    }
}

// cmOutputRequiredFilesCommand
bool cmOutputRequiredFilesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() != 2 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  // store the arg for final pass
  this->File = args[0];
  this->OutputFile = args[1];
  
  // compute the list of files
  cmLBDepend md;
  md.SetMakefile(this->Makefile);
  md.AddSearchPath(this->Makefile->GetStartDirectory());
  // find the depends for a file
  const cmDependInformation *info = md.FindDependencies(this->File.c_str());
  if (info)
    {
    // write them out
    FILE *fout = fopen(this->OutputFile.c_str(),"w");
    std::set<cmDependInformation const*> visited;
    this->ListDependencies(info,fout, &visited);
    fclose(fout);
    }

  return true;
}

void cmOutputRequiredFilesCommand::
ListDependencies(cmDependInformation const *info,
                 FILE *fout,
                 std::set<cmDependInformation const*> *visited)
{
  // add info to the visited set
  visited->insert(info);
  // now recurse with info's dependencies
  for(cmDependInformation::DependencySetType::const_iterator d = 
        info->DependencySet.begin();
      d != info->DependencySet.end(); ++d)
    {
    if (visited->find(*d) == visited->end())
      {
      if(info->FullPath != "")
        {
        std::string tmp = (*d)->FullPath;
        std::string::size_type pos = tmp.rfind('.');
        if(pos != std::string::npos && (tmp.substr(pos) != ".h"))
          {
          tmp = tmp.substr(0, pos);
          fprintf(fout,"%s\n",(*d)->FullPath.c_str());
          }
        }
      this->ListDependencies(*d,fout,visited);
      }
    }
}

