context: using System;
  using System.IO;
  using System.Reflection;
  using USC.GISResearchLab.Common.Utils.Directories;
  using USC.GISResearchLab.Common.Utils.Strings;
  
  namespace USC.GISResearchLab.Common.Utils.Files
  {
      /// <summary>
      /// Summary description for FileUtils.
      /// </summary>
      public class FileUtils
      {
  
          public static string GetFirstSubdirectoryPathFromPattern(string basePath, string patternPath, string fileName)
          {
              string subDirectoryPath = DirectoryUtils.GetFirstSubDirectoryPath(basePath);
              string subDirectoryName = DirectoryUtils.GetDirectoryName(subDirectoryPath);
              string[] subsitutionNamesValues = new string[] { "{BASE}=" + basePath, "{DIR}=" + subDirectoryName, "{FILE}=" + fileName };
              return EvaluatePathFromPattern(patternPath, subsitutionNamesValues);
          }
  
          public static string GetCurrentAssemblyDirectory()
          {
  
              string codeBase = Assembly.GetExecutingAssembly().CodeBase;
              UriBuilder uri = new UriBuilder(codeBase);
              string path = Uri.UnescapeDataString(uri.Path);
              return Path.GetDirectoryName(path);
  
          }
  
          //public static string EvaluatePathFromTreePattern(string basePath, string subDirectoryName, string patternPath, string fileName)
          //{
          //    if (basePath == null)
          //    {
          //        throw new Exception("EvaluatePathFromTreePattern error: basePath is null");
          //    }
          //    if (subDirectoryName == null)
          //    {
          //        throw new Exception("EvaluatePathFromTreePattern error: subDirectoryName is null");
          //    }
          //    if (patternPath == null)
          //    {
          //        throw new Exception("EvaluatePathFromTreePattern error: patternPath is null");
          //    }
          //    if (fileName == null)
          //    {
          //        throw new Exception("EvaluatePathFromTreePattern error: fileName is null");
          //    }
  
          //    if (patternPath.IndexOf("{BASE}") != -1)
          //    {
          //        while (patternPath.IndexOf("{BASE}") != -1)
          //        {
          //            patternPath = patternPath.Replace("{BASE}", basePath);
          //        }
          //    }
  
          //    if (patternPath.IndexOf("{DIR}") != -1)
          //    {
          //        while (patternPath.IndexOf("{DIR}") != -1)
          //        {
          //            patternPath = patternPath.Replace("{DIR}", subDirectoryName);
          //        }
          //    }
  
          //    if (patternPath.IndexOf("{FILE}") != -1)
          //    {
          //        while (patternPath.IndexOf("{FILE}") != -1)
          //        {
          //            patternPath = patternPath.Replace("{FILE}", fileName);
          //        }
          //    }
  
          //    patternPath = patternPath.Replace(@"\\", @"\");
  
          //    return patternPath;
          //}
  
          public static string EvaluatePathFromPattern(string patternPath, string[] subsitutionNamesValues)
          {
              if (patternPath != null)
              {
                  if (subsitutionNamesValues != null)
                  {
                      for (int i = 0; i < subsitutionNamesValues.Length; i++)
                      {
                          string[] parts = subsitutionNamesValues[i].Split('=');
                          string sub = parts[0];
                          string val = parts[1];
                          if (sub != null && val != null)
                          {
                              while (patternPath.IndexOf(sub) != -1)
                              {
                                  patternPath = patternPath.Replace(sub, val);
                              }
                          }
                      }
                  }
  
                  patternPath = patternPath.Replace(@"\\", @"\");
              }
  
              return patternPath;
          }
  
          public static byte[] AsBytes(string filePath)
          {
              byte[] ret = null;
              long numBytes = 0;
              try
              {
                  FileInfo fileInfo = new FileInfo(filePath);
                  numBytes = fileInfo.Length;
                  FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                  BinaryReader binaryReader = new BinaryReader(fileStream);
                  ret = binaryReader.ReadBytes((int)numBytes);
                  binaryReader.Close();
                  fileStream.Close();
              }
              catch (Exception e)
              {
                  throw new Exception("Error reading file as bytes: " + filePath + " - " + e.Message, e);
              }
              return ret;
          }
  
          public static int GetBytesAtOffset(ref byte[] buffer, string filePath, int startPosition, int size)
          {
              int ret = -1;
              try
              {
                  FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                  BinaryReader binaryReader = new BinaryReader(fileStream);
                  binaryReader.BaseStream.Seek(startPosition, SeekOrigin.Begin);
                  ret = binaryReader.Read(buffer, 0, size);
                  binaryReader.Close();
                  fileStream.Close();
              }
              catch (Exception e)
              {
                  throw new Exception("Error reading file as bytes: " + filePath + " - " + e.Message, e);
              }
              return ret;
          }
  
          public static bool SaveBytes(byte[] data, long numBytes, string filePath)
          {
              bool ret = false;
              try
              {
                  {
                      FileStream fileStream = new FileStream(filePath, FileMode.CreateNew);
                      BinaryWriter binaryWriter = new BinaryWriter(fileStream);
  
                      for (int i = 0; i < numBytes; i++)
                      {
                          binaryWriter.Write(data[i]);
                      }
  
                      binaryWriter.Close();
                      fileStream.Close();
                      ret = true;
                  }
              }
              catch (Exception e)
              {
                  throw new Exception("Error writing bytes to file: " + filePath, e);
              }
  
              return ret;
          }
  
          public static string GetNextIncrementalFileName(string filePath)
          {
              string ret = filePath;
  
              while (FileExists(ret))
              {
  
                  string path = GetDirectoryPath(ret);
                  string ext = GetExtension(ret);
                  string name = GetFileNameWithoutExtension(ret);
                  string incrementedName = StringUtils.GetNextIncrementalString(name);
  
                  ret = path + incrementedName + ext;
  
              }
              return ret;
          }
  
  
          public static bool IsFileLocked(string filePath)
          {
              bool ret = false;
  
              if (File.Exists(filePath))
              {
                  FileInfo fileInfo = new FileInfo(filePath);
                  ret = IsFileLocked(fileInfo);
              }
  
              return ret;
          }
  
          public static bool IsFileLocked(FileInfo file)
          {
              FileStream stream = null;
  
              try
              {
                  stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
              }
              catch (IOException)
              {
                  //the file is unavailable because it is:
                  //still being written to
                  //or being processed by another thread
                  //or does not exist (has already been processed)
                  return true;
              }
              finally
              {
                  if (stream != null)
                      stream.Close();
              }
  
              //file is not locked
              return false;
          }
  
          public static bool TestPath(string path, bool createIfNeeded, bool throwError)
          {
              bool ret = true;
  
              if (!FileExists(path))
              {
                  ret = false;
                  if (throwError)
                  {
                      throw new FileNotFoundException("File not found: " + path);
                  }
                  else if (createIfNeeded)
                  {
                      File.CreateText(path);
                      ret = true;
                  }
              }
  
              return ret;
          }
  
          public static string AsString(string path)
          {
              string ret = null;
              try
              {
                  TextReader textReader = new StreamReader(path);
                  ret = textReader.ReadToEnd();
                  textReader.Close();
              }
              catch (Exception e)
              {
                  throw new Exception("Error reading file as string: " + path, e);
              }
              return ret;
          }
  
          public static void ReplaceContents(string path, string contents)
          {
              OverwriteTextFile(path, contents);
          }
  
          public static bool FileExists(string path)
          {
              bool ret = false;
              if (!StringUtils.IsEmpty(path))
              {
  
                  try
                  {
                      FileInfo file = new FileInfo(path);
                      if (file.Exists)
                      {
                          ret = true;
                      }
                  }
                  catch (Exception e)
                  {
                      throw new Exception("Error in FileExists() - " + e.Message, e);
                  }
              }
              return ret;
          }
  
          public static string GetFileNameWithoutExtension(string filePath)
          {
              string ret = "";
              if (!String.IsNullOrEmpty(filePath))
              {
                  ret = Path.GetFileNameWithoutExtension(filePath);
              }
              return ret;
          }
  
          public static string GetFileNameFromPath(string filePath)
          {
              string ret = "";
              if (!String.IsNullOrEmpty(filePath))
              {
                  ret = Path.GetFileName(filePath);
              }
              return ret;
          }
  
          public static string GetDrive(string filePath)
          {
              string ret = "";
              if (!String.IsNullOrEmpty(filePath))
              {
                  ret = DirectoryUtils.GetDrive(filePath);
              }
              return ret;
          }
  
          public static string GetDirectoryPath(string filePath)
          {
              string ret = "";
              if (!String.IsNullOrEmpty(filePath))
              {
                  ret = GetDirectoryPath(filePath, true);
              }
              return ret;
          }
  
          public static string GetDirectoryPathName(string filePath)
          {
              string ret = "";
              if (!String.IsNullOrEmpty(filePath))
              {
                  string directoryPath = GetDirectoryPath(filePath, true);
                  ret = DirectoryUtils.GetDirectoryName(directoryPath);
              }
              return ret;
          }
  
  
          public static string GetDirectoryPath(string filePath, bool includeTrailingSlash)
          {
              string ret = "";
              if (filePath != null)
              {
                  if (!filePath.Equals(""))
                  {
                      ret = (Path.GetDirectoryName(filePath));
                      if (includeTrailingSlash)
                      {
                          ret += "\\";
                      }
                  }
                  else
                  {
                      throw new Exception("FileUtils.GetDirectoryPath() error: filePath empty");
                  }
              }
              else
              {
                  throw new Exception("FileUtils.GetDirectoryPath() error: filePath is null");
              }
              return ret;
          }
  
          public static string GetDirectoryName(string filePath)
          {
              string ret = "";
              if (filePath != null)
              {
                  if (!filePath.Equals(""))
                  {
                      ret = Directory.GetParent(filePath).Name;
                  }
                  else
                  {
                      throw new Exception("FileUtils.GetDirectoryName() error: filePath empty");
                  }
              }
              else
              {
                  throw new Exception("FileUtils.GetDirectoryName() error: filePath is null");
              }
              return ret;
          }
  
          public static string GetFileSizeScaled(string filePath)
          {
              double size = GetFileSize(filePath);
              return GetFileSizeScaled(size);
          }
  
          public static string GetFileSizeScaled(double size)
          {
              string ret = "";
              string scale;
  
              if (size > 1000000000.0)
              {
                  size = (size / 1000000000.0);
                  scale = " GB";
              }
              else if (size > 1000000.0)
              {
                  size = (size / 1000000.0);
                  scale = " MB";
              }
              else if (size > 1000.0)
              {
                  size = (size / 1000.0);
                  scale = " KB";
              }
              else
              {
                  scale = " B";
              }
  
              size = System.Math.Round(size, 2);
  
gt:             ret = size + scale;