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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmFileTimeComparison.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 "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;
    }
}
