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

// Use a hash table to avoid duplicate file time checks from disk.
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include <cmsys/hash_map.hxx>
#endif

// Use a platform-specific API to get file times efficiently.
#if !defined(_WIN32) || defined(__CYGWIN__)
#  define cmFileTimeComparison_Type struct stat
#  include <ctype.h>
#  include <sys/stat.h>
#else
#  define cmFileTimeComparison_Type FILETIME
#  include <windows.h>
#endif

//----------------------------------------------------------------------------
class cmFileTimeComparisonInternal
{
public:
  // Internal comparison method.
  inline bool FileTimeCompare(const char* f1, const char* f2, int* result);

  bool FileTimesDiffer(const char* f1, const char* f2);

private:
#if defined(CMAKE_BUILD_WITH_CMAKE)
  // Use a hash table to efficiently map from file name to modification time.
  class HashString
    {
  public:
    size_t operator()(const cmStdString& s) const
      {
      return h(s.c_str());
      }
    cmsys::hash<const char*> h;
    };
  typedef cmsys::hash_map<cmStdString,
                          cmFileTimeComparison_Type, HashString> FileStatsMap;
  FileStatsMap Files;
#endif

  // Internal methods to lookup and compare modification times.
  inline bool Stat(const char* fname, cmFileTimeComparison_Type* st);
  inline int Compare(cmFileTimeComparison_Type* st1,
                     cmFileTimeComparison_Type* st2);
  inline bool TimesDiffer(cmFileTimeComparison_Type* st1,
                          cmFileTimeComparison_Type* st2);
};

//----------------------------------------------------------------------------
bool cmFileTimeComparisonInternal::Stat(const char* fname,
                                        cmFileTimeComparison_Type* st)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
  // Use the stored time if available.
  cmFileTimeComparisonInternal::FileStatsMap::iterator fit =
    this->Files.find(fname);
  if ( fit != this->Files.end() )
    {
    *st = fit->second;
    return true;
    }
#endif

#if !defined(_WIN32) || defined(__CYGWIN__)
  // POSIX version.  Use the stat function.
  int res = ::stat(fname, st);
  if ( res != 0 )
    {
    return false;
    }
#else
  // Windows version.  Get the modification time from extended file
  // attributes.
  WIN32_FILE_ATTRIBUTE_DATA fdata;
  if(!GetFileAttributesEx(fname, GetFileExInfoStandard, &fdata))
    {
    return false;
    }

  // Copy the file time to the output location.
  *st = fdata.ftLastWriteTime;
#endif

#if defined(CMAKE_BUILD_WITH_CMAKE)
  // Store the time for future use.
  this->Files[fname] = *st;
#endif

  return true;
}

//----------------------------------------------------------------------------
cmFileTimeComparison::cmFileTimeComparison()
{
  this->Internals = new cmFileTimeComparisonInternal;
}

//----------------------------------------------------------------------------
cmFileTimeComparison::~cmFileTimeComparison()
{
  delete this->Internals;
}

//----------------------------------------------------------------------------
bool cmFileTimeComparison::FileTimeCompare(const char* f1, 
                                           const char* f2, int* result)
{
  return this->Internals->FileTimeCompare(f1, f2, result);
}

//----------------------------------------------------------------------------
bool cmFileTimeComparison::FileTimesDiffer(const char* f1, const char* f2)
{
  return this->Internals->FileTimesDiffer(f1, f2);
}

//----------------------------------------------------------------------------
int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1, 
                                          cmFileTimeComparison_Type* s2)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
# if cmsys_STAT_HAS_ST_MTIM
  // Compare using nanosecond resolution.
  if(s1->st_mtim.tv_sec < s2->st_mtim.tv_sec)
    {
    return -1;
    }
  else if(s1->st_mtim.tv_sec > s2->st_mtim.tv_sec)
    {
    return 1;
    }
  else if(s1->st_mtim.tv_nsec < s2->st_mtim.tv_nsec)
    {
    return -1;
    }
  else if(s1->st_mtim.tv_nsec > s2->st_mtim.tv_nsec)
    {
    return 1;
    }
# else
  // Compare using 1 second resolution.
  if(s1->st_mtime < s2->st_mtime)
    {
    return -1;
    }
  else if(s1->st_mtime > s2->st_mtime)
    {
    return 1;
    }
# endif
  // Files have the same time.
  return 0;
#else
  // Compare using system-provided function.
  return (int)CompareFileTime(s1, s2);
#endif
}

//----------------------------------------------------------------------------
bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1,
                                               cmFileTimeComparison_Type* s2)
{
#if !defined(_WIN32) || defined(__CYGWIN__)
# if cmsys_STAT_HAS_ST_MTIM
  // Times are integers in units of 1ns.
  long long bil = 1000000000;
  long long t1 = s1->st_mtim.tv_sec * bil + s1->st_mtim.tv_nsec;
  long long t2 = s2->st_mtim.tv_sec * bil + s2->st_mtim.tv_nsec;
  if(t1 < t2)
    {
    return (t2 - t1) >= bil;
    }
  else if(t2 < t1)
    {
    return (t1 - t2) >= bil;
    }
  else
    {
    return false;
    }
# else
  // Times are integers in units of 1s.
  if(s1->st_mtime < s2->st_mtime)
    {
    return (s2->st_mtime - s1->st_mtime) >= 1;
    }
  else if(s1->st_mtime > s2->st_mtime)
    {
    return (s1->st_mtime - s2->st_mtime) >= 1;
    }
  else
    {
    return false;
    }
# endif
#else
  // Times are integers in units of 100ns.
  LARGE_INTEGER t1;
  LARGE_INTEGER t2;
  t1.LowPart = s1->dwLowDateTime;
  t1.HighPart = s1->dwHighDateTime;
  t2.LowPart = s2->dwLowDateTime;
  t2.HighPart = s2->dwHighDateTime;
  if(t1.QuadPart < t2.QuadPart)
    {
    return (t2.QuadPart - t1.QuadPart) >= static_cast<LONGLONG>(10000000);
    }
  else if(t2.QuadPart < t1.QuadPart)
    {
    return (t1.QuadPart - t2.QuadPart) >= static_cast<LONGLONG>(10000000);
    }
  else
    {
    return false;
    }
#endif
}

//----------------------------------------------------------------------------
bool cmFileTimeComparisonInternal::FileTimeCompare(const char* f1,
                                                   const char* f2,
                                                   int* result)
{
  // Get the modification time for each file.
  cmFileTimeComparison_Type s1;
  cmFileTimeComparison_Type s2;
  if(this->Stat(f1, &s1) &&
     this->Stat(f2, &s2))
    {
    // Compare the two modification times.
    *result = this->Compare(&s1, &s2);
    return true;
    }
  else
    {
    // No comparison available.  Default to the same time.
    *result = 0;
    return false;
    }
}

//----------------------------------------------------------------------------
bool cmFileTimeComparisonInternal::FileTimesDiffer(const char* f1,
                                                   const char* f2)
{
  // Get the modification time for each file.
  cmFileTimeComparison_Type s1;
  cmFileTimeComparison_Type s2;
  if(this->Stat(f1, &s1) &&
     this->Stat(f2, &s2))
    {
    // Compare the two modification times.
    return this->TimesDiffer(&s1, &s2);
    }
  else
    {
    // No comparison available.  Default to different times.
    return true;
    }
}
