/*============================================================================
  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 "cmDependsC.h"

#include "cmFileTimeComparison.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"

#include <ctype.h> // isspace


#define INCLUDE_REGEX_LINE \
  "^[ \t]*#[ \t]*(include|import)[ \t]*[<\"]([^\">]+)([\">])"

#define INCLUDE_REGEX_LINE_MARKER "#IncludeRegexLine: "
#define INCLUDE_REGEX_SCAN_MARKER "#IncludeRegexScan: "
#define INCLUDE_REGEX_COMPLAIN_MARKER "#IncludeRegexComplain: "
#define INCLUDE_REGEX_TRANSFORM_MARKER "#IncludeRegexTransform: "

//----------------------------------------------------------------------------
cmDependsC::cmDependsC()
: ValidDeps(0)
{
}

//----------------------------------------------------------------------------
cmDependsC::cmDependsC(cmLocalGenerator* lg,
                   const char* targetDir,
                   const char* lang,
                   const std::map<std::string, DependencyVector>* validDeps)
: cmDepends(lg, targetDir)
, ValidDeps(validDeps)
{
  cmMakefile* mf = lg->GetMakefile();

  // Configure the include file search path.
  this->SetIncludePathFromLanguage(lang);

  // Configure regular expressions.
  std::string scanRegex = "^.*$";
  std::string complainRegex = "^$";
  {
  std::string scanRegexVar = "CMAKE_";
  scanRegexVar += lang;
  scanRegexVar += "_INCLUDE_REGEX_SCAN";
  if(const char* sr = mf->GetDefinition(scanRegexVar.c_str()))
    {
    scanRegex = sr;
    }
  std::string complainRegexVar = "CMAKE_";
  complainRegexVar += lang;
  complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
  if(const char* cr = mf->GetDefinition(complainRegexVar.c_str()))
    {
    complainRegex = cr;
    }
  }

  this->IncludeRegexLine.compile(INCLUDE_REGEX_LINE);
  this->IncludeRegexScan.compile(scanRegex.c_str());
  this->IncludeRegexComplain.compile(complainRegex.c_str());
  this->IncludeRegexLineString = INCLUDE_REGEX_LINE_MARKER INCLUDE_REGEX_LINE;
  this->IncludeRegexScanString = INCLUDE_REGEX_SCAN_MARKER;
  this->IncludeRegexScanString += scanRegex;
  this->IncludeRegexComplainString = INCLUDE_REGEX_COMPLAIN_MARKER;
  this->IncludeRegexComplainString += complainRegex;

  this->SetupTransforms();

  this->CacheFileName = this->TargetDirectory;
  this->CacheFileName += "/";
  this->CacheFileName += lang;
  this->CacheFileName += ".includecache";

  this->ReadCacheFile();
}

//----------------------------------------------------------------------------
cmDependsC::~cmDependsC()
{
  this->WriteCacheFile();

  for (std::map<cmStdString, cmIncludeLines*>::iterator it=
         this->FileCache.begin(); it!=this->FileCache.end(); ++it)
    {
    delete it->second;
    }
}

//----------------------------------------------------------------------------
bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
                                   const std::string& obj,
                                   std::ostream& makeDepends,
                                   std::ostream& internalDepends)
{
  // Make sure this is a scanning instance.
  if(sources.empty() || sources.begin()->empty())
    {
    cmSystemTools::Error("Cannot scan dependencies without a source file.");
    return false;
    }
  if(obj.empty())
    {
    cmSystemTools::Error("Cannot scan dependencies without an object file.");
    return false;
    }

  std::set<cmStdString> dependencies;
  bool haveDeps = false;

  if (this->ValidDeps != 0)
    {
    std::map<std::string, DependencyVector>::const_iterator tmpIt =
                                                    this->ValidDeps->find(obj);
    if (tmpIt!= this->ValidDeps->end())
      {
      for(DependencyVector::const_iterator i=tmpIt->second.begin();
         i != tmpIt->second.end(); ++i)
        {
        dependencies.insert(*i);
        }
      haveDeps = true;
      }
    }

  if (!haveDeps)
    {
    // Walk the dependency graph starting with the source file.
    int srcFiles = (int)sources.size();
    this->Encountered.clear();

    for(std::set<std::string>::const_iterator srcIt = sources.begin();
        srcIt != sources.end(); ++srcIt)
      {
      UnscannedEntry root;
      root.FileName = *srcIt;
      this->Unscanned.push(root);
      this->Encountered.insert(*srcIt);
      }

    std::set<cmStdString> scanned;

    // Use reserve to allocate enough memory for tempPathStr
    // so that during the loops no memory is allocated or freed
    std::string tempPathStr;
    tempPathStr.reserve(4*1024);

    while(!this->Unscanned.empty())
      {
      // Get the next file to scan.
      UnscannedEntry current = this->Unscanned.front();
      this->Unscanned.pop();

      // If not a full path, find the file in the include path.
      std::string fullName;
      if((srcFiles>0)
         || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
        {
        if(cmSystemTools::FileExists(current.FileName.c_str(), true))
          {
          fullName = current.FileName;
          }
        }
      else if(!current.QuotedLocation.empty() &&
              cmSystemTools::FileExists(current.QuotedLocation.c_str(), true))
        {
        // The include statement producing this entry was a double-quote
        // include and the included file is present in the directory of
        // the source containing the include statement.
        fullName = current.QuotedLocation;
        }
      else
        {
        std::map<cmStdString, cmStdString>::iterator
          headerLocationIt=this->HeaderLocationCache.find(current.FileName);
        if (headerLocationIt!=this->HeaderLocationCache.end())
          {
          fullName=headerLocationIt->second;
          }
        else for(std::vector<std::string>::const_iterator i =
              this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
          {
          // Construct the name of the file as if it were in the current
          // include directory.  Avoid using a leading "./".

          tempPathStr =
            cmSystemTools::CollapseCombinedPath(*i, current.FileName);

          // Look for the file in this location.
          if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
            {
            fullName = tempPathStr;
            HeaderLocationCache[current.FileName]=fullName;
            break;
            }
          }
        }

      // Complain if the file cannot be found and matches the complain
      // regex.
      if(fullName.empty() &&
        this->IncludeRegexComplain.find(current.FileName.c_str()))
        {
        cmSystemTools::Error("Cannot find file \"",
                            current.FileName.c_str(), "\".");
        return false;
        }

      // Scan the file if it was found and has not been scanned already.
      if(!fullName.empty() && (scanned.find(fullName) == scanned.end()))
        {
        // Record scanned files.
        scanned.insert(fullName);

        // Check whether this file is already in the cache
        std::map<cmStdString, cmIncludeLines*>::iterator fileIt=
          this->FileCache.find(fullName);
        if (fileIt!=this->FileCache.end())
          {
          fileIt->second->Used=true;
          dependencies.insert(fullName);
          for (std::vector<UnscannedEntry>::const_iterator incIt=
                fileIt->second->UnscannedEntries.begin();
              incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
            {
            if (this->Encountered.find(incIt->FileName) ==
                this->Encountered.end())
              {
              this->Encountered.insert(incIt->FileName);
              this->Unscanned.push(*incIt);
              }
            }
          }
        else
          {

          // Try to scan the file.  Just leave it out if we cannot find
          // it.
          std::ifstream fin(fullName.c_str());
          if(fin)
            {
            // Add this file as a dependency.
            dependencies.insert(fullName);

            // Scan this file for new dependencies.  Pass the directory
            // containing the file to handle double-quote includes.
            std::string dir = cmSystemTools::GetFilenamePath(fullName);
            this->Scan(fin, dir.c_str(), fullName);
            }
          }
        }

      srcFiles--;
      }
    }

  // Write the dependencies to the output stream.  Makefile rules
  // written by the original local generator for this directory
  // convert the dependencies to paths relative to the home output
  // directory.  We must do the same here.
  internalDepends << obj << std::endl;
  for(std::set<cmStdString>::const_iterator i=dependencies.begin();
      i != dependencies.end(); ++i)
    {
    makeDepends << obj << ": " <<
      this->LocalGenerator->Convert(i->c_str(),
                                    cmLocalGenerator::HOME_OUTPUT,
                                    cmLocalGenerator::MAKEFILE)
                << std::endl;
    internalDepends << " " << i->c_str() << std::endl;
    }
  makeDepends << std::endl;

  return true;
}

//----------------------------------------------------------------------------
void cmDependsC::ReadCacheFile()
{
  if(this->CacheFileName.size() == 0)
    {
    return;
    }
  std::ifstream fin(this->CacheFileName.c_str());
  if(!fin)
    {
    return;
    }

  std::string line;
  cmIncludeLines* cacheEntry=0;
  bool haveFileName=false;

  while(cmSystemTools::GetLineFromStream(fin, line))
    {
    if (line.empty())
      {
      cacheEntry=0;
      haveFileName=false;
      continue;
      }
    //the first line after an empty line is the name of the parsed file
    if (haveFileName==false)
      {
      haveFileName=true;
      int newer=0;
      cmFileTimeComparison comp;
      bool res=comp.FileTimeCompare(this->CacheFileName.c_str(),
                                    line.c_str(), &newer);

      if ((res==true) && (newer==1)) //cache is newer than the parsed file
        {
        cacheEntry=new cmIncludeLines;
        this->FileCache[line]=cacheEntry;
        }
      // file doesn't exist, check that the regular expressions
      // haven't changed
      else if (res==false)
        {
        if (line.find(INCLUDE_REGEX_LINE_MARKER) == 0)
          {
          if (line != this->IncludeRegexLineString)
            {
            return;
            }
          }
        else if (line.find(INCLUDE_REGEX_SCAN_MARKER) == 0)
          {
          if (line != this->IncludeRegexScanString)
            {
            return;
            }
          }
        else if (line.find(INCLUDE_REGEX_COMPLAIN_MARKER) == 0)
          {
          if (line != this->IncludeRegexComplainString)
            {
            return;
            }
          }
        else if (line.find(INCLUDE_REGEX_TRANSFORM_MARKER) == 0)
          {
          if (line != this->IncludeRegexTransformString)
            {
            return;
            }
          }
        }
      }
    else if (cacheEntry!=0)
      {
      UnscannedEntry entry;
      entry.FileName = line;
      if (cmSystemTools::GetLineFromStream(fin, line))
        {
        if (line!="-")
          {
          entry.QuotedLocation=line;
          }
        cacheEntry->UnscannedEntries.push_back(entry);
        }
      }
    }
}

//----------------------------------------------------------------------------
void cmDependsC::WriteCacheFile() const
{
  if(this->CacheFileName.size() == 0)
    {
    return;
    }
  std::ofstream cacheOut(this->CacheFileName.c_str());
  if(!cacheOut)
    {
    return;
    }

  cacheOut << this->IncludeRegexLineString << "\n\n";
  cacheOut << this->IncludeRegexScanString << "\n\n";
  cacheOut << this->IncludeRegexComplainString << "\n\n";
  cacheOut << this->IncludeRegexTransformString << "\n\n";

  for (std::map<cmStdString, cmIncludeLines*>::const_iterator fileIt=
         this->FileCache.begin();
       fileIt!=this->FileCache.end(); ++fileIt)
    {
    if (fileIt->second->Used)
      {
      cacheOut<<fileIt->first.c_str()<<std::endl;

      for (std::vector<UnscannedEntry>::const_iterator
             incIt=fileIt->second->UnscannedEntries.begin();
           incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
        {
        cacheOut<<incIt->FileName.c_str()<<std::endl;
        if (incIt->QuotedLocation.empty())
          {
          cacheOut<<"-"<<std::endl;
          }
        else
          {
          cacheOut<<incIt->QuotedLocation.c_str()<<std::endl;
          }
        }
      cacheOut<<std::endl;
      }
   }
}

//----------------------------------------------------------------------------
void cmDependsC::Scan(std::istream& is, const char* directory,
  const cmStdString& fullName)
{
  cmIncludeLines* newCacheEntry=new cmIncludeLines;
  newCacheEntry->Used=true;
  this->FileCache[fullName]=newCacheEntry;

  // Read one line at a time.
  std::string line;
  while(cmSystemTools::GetLineFromStream(is, line))
    {
    // Transform the line content first.
    if(!this->TransformRules.empty())
      {
      this->TransformLine(line);
      }

    // Match include directives.
    if(this->IncludeRegexLine.find(line.c_str()))
      {
      // Get the file being included.
      UnscannedEntry entry;
      entry.FileName = this->IncludeRegexLine.match(2);
      cmSystemTools::ConvertToUnixSlashes(entry.FileName);
      if(this->IncludeRegexLine.match(3) == "\"" &&
         !cmSystemTools::FileIsFullPath(entry.FileName.c_str()))
        {
        // This was a double-quoted include with a relative path.  We
        // must check for the file in the directory containing the
        // file we are scanning.
        entry.QuotedLocation =
          cmSystemTools::CollapseCombinedPath(directory, entry.FileName);
        }

      // Queue the file if it has not yet been encountered and it
      // matches the regular expression for recursive scanning.  Note
      // that this check does not account for the possibility of two
      // headers with the same name in different directories when one
      // is included by double-quotes and the other by angle brackets.
      // It also does not work properly if two header files with the same
      // name exist in different directories, and both are included from a
      // file their own directory by simply using "filename.h" (#12619)
      // This kind of problem will be fixed when a more
      // preprocessor-like implementation of this scanner is created.
      if (this->IncludeRegexScan.find(entry.FileName.c_str()))
        {
        newCacheEntry->UnscannedEntries.push_back(entry);
        if(this->Encountered.find(entry.FileName) == this->Encountered.end())
          {
          this->Encountered.insert(entry.FileName);
          this->Unscanned.push(entry);
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
void cmDependsC::SetupTransforms()
{
  // Get the transformation rules.
  std::vector<std::string> transformRules;
  cmMakefile* mf = this->LocalGenerator->GetMakefile();
  if(const char* xform =
     mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS"))
    {
    cmSystemTools::ExpandListArgument(xform, transformRules, true);
    }
  for(std::vector<std::string>::const_iterator tri = transformRules.begin();
      tri != transformRules.end(); ++tri)
    {
    this->ParseTransform(*tri);
    }

  this->IncludeRegexTransformString = INCLUDE_REGEX_TRANSFORM_MARKER;
  if(!this->TransformRules.empty())
    {
    // Construct the regular expression to match lines to be
    // transformed.
    std::string xform = "^([ \t]*#[ \t]*(include|import)[ \t]*)(";
    const char* sep = "";
    for(TransformRulesType::const_iterator tri = this->TransformRules.begin();
        tri != this->TransformRules.end(); ++tri)
      {
      xform += sep;
      xform += tri->first;
      sep = "|";
      }
    xform += ")[ \t]*\\(([^),]*)\\)";
    this->IncludeRegexTransform.compile(xform.c_str());

    // Build a string that encodes all transformation rules and will
    // change when rules are changed.
    this->IncludeRegexTransformString += xform;
    for(TransformRulesType::const_iterator tri = this->TransformRules.begin();
        tri != this->TransformRules.end(); ++tri)
      {
      this->IncludeRegexTransformString += " ";
      this->IncludeRegexTransformString += tri->first;
      this->IncludeRegexTransformString += "(%)=";
      this->IncludeRegexTransformString += tri->second;
      }
    }
}

//----------------------------------------------------------------------------
void cmDependsC::ParseTransform(std::string const& xform)
{
  // A transform rule is of the form SOME_MACRO(%)=value-with-%
  // We can simply separate with "(%)=".
  std::string::size_type pos = xform.find("(%)=");
  if(pos == xform.npos || pos == 0)
    {
    return;
    }
  std::string name = xform.substr(0, pos);
  std::string value = xform.substr(pos+4, xform.npos);
  this->TransformRules[name] = value;
}

//----------------------------------------------------------------------------
void cmDependsC::TransformLine(std::string& line)
{
  // Check for a transform rule match.  Return if none.
  if(!this->IncludeRegexTransform.find(line.c_str()))
    {
    return;
    }
  TransformRulesType::const_iterator tri =
    this->TransformRules.find(this->IncludeRegexTransform.match(3));
  if(tri == this->TransformRules.end())
    {
    return;
    }

  // Construct the transformed line.
  std::string newline = this->IncludeRegexTransform.match(1);
  std::string arg = this->IncludeRegexTransform.match(4);
  for(const char* c = tri->second.c_str(); *c; ++c)
    {
    if(*c == '%')
      {
      newline += arg;
      }
    else
      {
      newline += *c;
      }
    }

  // Return the transformed line.
  line = newline;
}
