/*============================================================================
  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 "cmAlgorithms.h"
#include <cmsys/FStream.hxx>

#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 std::string& 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))
    {
    scanRegex = sr;
    }
  std::string complainRegexVar = "CMAKE_";
  complainRegexVar += lang;
  complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
  if(const char* cr = mf->GetDefinition(complainRegexVar))
    {
    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();
  cmDeleteAll(this->FileCache);
}

//----------------------------------------------------------------------------
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<std::string> 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())
      {
      dependencies.insert(tmpIt->second.begin(), tmpIt->second.end());
      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<std::string> 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<std::string, std::string>::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<std::string, 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.
          cmsys::ifstream fin(fullName.c_str());
          if(fin)
            {
            cmsys::FStream::BOM bom = cmsys::FStream::ReadBOM(fin);
            if(bom == cmsys::FStream::BOM_None ||
               bom == cmsys::FStream::BOM_UTF8)
              {
              // 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);
              }
            else
              {
              // Skip file with encoding we do not implement.
              }
            }
          }
        }

      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.
  std::string obj_i =
    this->LocalGenerator->Convert(obj, cmLocalGenerator::HOME_OUTPUT);
  std::string obj_m =
    this->LocalGenerator->ConvertToOutputFormat(obj_i,
                                                cmLocalGenerator::MAKERULE);
  internalDepends << obj_i << std::endl;

  for(std::set<std::string>::const_iterator i=dependencies.begin();
      i != dependencies.end(); ++i)
    {
    makeDepends << obj_m << ": " <<
      this->LocalGenerator->Convert(*i,
                                    cmLocalGenerator::HOME_OUTPUT,
                                    cmLocalGenerator::MAKERULE)
                << std::endl;
    internalDepends << " " << *i << std::endl;
    }
  makeDepends << std::endl;

  return true;
}

//----------------------------------------------------------------------------
void cmDependsC::ReadCacheFile()
{
  if(this->CacheFileName.empty())
    {
    return;
    }
  cmsys::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.empty())
    {
    return;
    }
  cmsys::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<std::string, 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 std::string& 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;
}
