import os
import tempfile
import fnmatch

def getAllFilesRecursively(in_allowedExtensionsGlobList, in_RootDir = '.'):
  """
  E.g.: getAllFilesRecursively(['*.txt'], './folder/to/files')
  E.g.: getAllFilesRecursively(['*.txt', '*.bat'])
  
  @note This function is ALWAYS recursive.
  @return List of fullpath string to files matching extensions provided.
  """
  
  assert( type([]) == type(in_allowedExtensionsGlobList) )
  
  fileList = []
  for root, subFolders, files in os.walk(in_RootDir):
    for file in files:
      
      add = False
      
      #@tag TODO: re-use filterFilesByExtension here
      for glob in in_allowedExtensionsGlobList:
        if fnmatch.fnmatch(file, glob):
          add = True
      
      if add:
        fullPathFile = os.path.join(root, file)
        normalizedFullPath = os.path.abspath(fullPathFile)
        fileList.append(normalizedFullPath)
  
  return fileList

class FileInfo:
  
  __FullPathFilename = None
  __FileSize = None
  
  def __init__(self, FullPathFilename_, FileSize_):
    self.__FullPathFilename = FullPathFilename_
    self.__FileSize = FileSize_
  
  def __lt__(self, other):
    return (self.__FileSize < other.__FileSize)
  
  def ToRow_NameAndSize(self, SepareAt = 100):
    FullPathStr = self.GetFilename()
    if len(FullPathStr) > SepareAt:
      FullPathStr = FullPathStr[len(FullPathStr)-SepareAt:]
    while len(FullPathStr) < SepareAt:
      FullPathStr+= " "
    return FullPathStr + " : " + str(self.GetFileSize()/1024) + 'k'

  def GetFilename(self):
    return self.__FullPathFilename
  
  def GetFileSize(self):
    return self.__FileSize

def GetBiggestFileList(SepareAt = 110, MaxNumFilesInReport = 150):
  lAllFilesListIncludingSubDirs = getAllFilesRecursively(['*.*'], '.')
  
  TotalDiskSpace = 0
  AllFileInfo = []
  
  for file in lAllFilesListIncludingSubDirs:
    try:
      lFileSize = os.path.getsize(file)
      TotalDiskSpace += lFileSize
      AllFileInfo.append( FileInfo(file, lFileSize) )
    #@tag Give a better output of why the file exception occurred
    #except Exception as inst:
    except Exception:
      print ("Error! " + file)
  
  AllFileInfo.sort()
  
  if( len(AllFileInfo)>MaxNumFilesInReport ):
    subAllFileInfo = AllFileInfo[-MaxNumFilesInReport:]
  else:
    subAllFileInfo = AllFileInfo
  
  Report = ''
  Report+= 'Total size: ' + str(TotalDiskSpace/1024) + "k\n"
  for lFileInfo in subAllFileInfo:
    Report += str(lFileInfo.ToRow_NameAndSize(SepareAt)) + "\n"
  
  return Report

if __name__ == '__main__':
  print (GetBiggestFileList())


