context: // Licensed to the Sio I/O Foundation under one or more agreements.
  // The Sio I/O Foundation licenses this file to you under the GNU General Public License v3.0 license.
  // See the LICENSE file in the project root for more information.
  
  // Licensed to the Sio I/O Foundation under one or more agreements.
  // The Sio I/O Foundation licenses this file to you under the GNU General Public License v3.0.
  // See the LICENSE file in the project root for more information.
  
  using Microsoft.AspNetCore.Http;
  using Sio.Cms.Lib.ViewModels;
  using Sio.Common.Helper;
  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.IO.Compression;
  using System.Linq;
  
  namespace Sio.Cms.Lib.Repositories
  {
      public class FileRepository
      {
          public string CurrentDirectory { get; set; }
  
          /// <summary>
          /// The instance
          /// </summary>
          private static volatile FileRepository instance;
  
          /// <summary>
          /// The synchronize root
          /// </summary>
          private static readonly object syncRoot = new Object();
  
          /// <summary>
          /// Gets the instance.
          /// </summary>
          /// <returns></returns>
          public static FileRepository Instance
          {
              get
              {
                  if (instance == null)
                  {
                      lock (syncRoot)
                      {
                          if (instance == null)
                              instance = new FileRepository();
                      }
                  }
                  return instance;
              }
              set
              {
                  instance = value;
              }
          }
  
          /// <summary>
          /// Prevents a default instance of the <see cref="FileRepository"/> class from being created.
          /// </summary>
          private FileRepository()
          {
              CurrentDirectory = Environment.CurrentDirectory;
          }
  
          public FileViewModel GetFile(string FilePath, List<FileViewModel> Files, string FileFolder)
          {
              var result = Files.Find(v => !string.IsNullOrEmpty(FilePath) && v.Filename == FilePath.Replace(@"\", "/").Split('/')[1]);
              return result ?? new FileViewModel() { FileFolder = FileFolder };
          }
  
          public FileViewModel GetWebFile(string filename, string folder)
          {
              string fullPath = $"{SioConstants.Folder.WebRootPath}/{folder}/{filename}";
              string folderPath = $"{SioConstants.Folder.WebRootPath}/{SioConstants.Folder.FileFolder}/{folder}";
              FileInfo file = new FileInfo(fullPath);
              FileViewModel result = null;
              try
              {
                  DirectoryInfo path = new DirectoryInfo(folderPath);
                  using (StreamReader s = file.OpenText())
                  {
                      result = new FileViewModel()
                      {
                          FolderName = path.Name,
                          FileFolder = folder,
                          Filename = file.Name.Substring(0, file.Name.LastIndexOf('.')),
                          Extension = file.Extension,
                          Content = s.ReadToEnd()
                      };
                  }
              }
              catch
              {
                  // File invalid
              }
  
              return result ?? new FileViewModel() { FileFolder = folder };
          }
  
          public bool DeleteWebFile(string filename, string folder)
          {
              string fullPath = CommonHelper.GetFullPath(new string[]
             {
                  SioConstants.Folder.WebRootPath,
                  SioConstants.Folder.FileFolder,
                  folder,
                  filename
             });
  
              if (File.Exists(fullPath))
              {
                  CommonHelper.RemoveFile(fullPath);
              }
              return true;
          }
  
          public bool DeleteWebFile(string filePath)
          {
              string fullPath = CommonHelper.GetFullPath(new string[]
             {
                  SioConstants.Folder.WebRootPath,
                  filePath
             });
  
              if (File.Exists(fullPath))
              {
                  CommonHelper.RemoveFile(fullPath);
              }
              return true;
          }
  
          public bool DeleteWebFolder(string folderPath)
          {
              string fullPath = CommonHelper.GetFullPath(new string[]
              {
                  SioConstants.Folder.WebRootPath,
                  folderPath
              });
  
              if (Directory.Exists(fullPath))
              {
                  Directory.Delete(fullPath, true);
              }
              return true;
          }
  
          public FileViewModel GetUploadFile(string name, string ext, string FileFolder)
          {
              FileViewModel result = null;
  
              string folder = CommonHelper.GetFullPath(new string[] { SioConstants.Folder.UploadFolder, FileFolder });
              string fullPath = string.Format(@"{0}/{1}.{2}", folder, name, ext);
  
              FileInfo file = new FileInfo(fullPath);
  
              try
              {
                  using (StreamReader s = file.OpenText())
                  {
                      result = new FileViewModel()
                      {
                          FileFolder = FileFolder,
                          Filename = file.Name.Substring(0, file.Name.LastIndexOf('.')),
                          Extension = file.Extension.Remove(0, 1),
                          Content = s.ReadToEnd()
                      };
                  }
              }
              catch
              {
                  // File invalid
              }
              return result ?? new FileViewModel() { FileFolder = FileFolder };
          }
  
          public FileViewModel GetFile(string name, string ext, string FileFolder, bool isCreate = false, string defaultContent = "")
          {
              FileViewModel result = null;
  
              string fullPath = Path.Combine(CurrentDirectory, FileFolder, string.Format("{0}{1}", name, ext));
  
              FileInfo file = new FileInfo(fullPath);
  
              if (file.Exists)
              {
                  try
                  {
                      using (StreamReader s = file.OpenText())
                      {
                          result = new FileViewModel()
                          {
                              FileFolder = FileFolder,
                              Filename = name,
                              Extension = ext,
                              Content = s.ReadToEnd()
                          };
                      }
                  }
                  catch
                  {
                      // File invalid
                  }
              }
              else if (isCreate)
              {
                  file.Create();
                  result = new FileViewModel()
                  {
                      FileFolder = FileFolder,
                      Filename = name,
                      Extension = ext,
                      Content = defaultContent
                  };
                  SaveFile(result);
              }
  
              return result ?? new FileViewModel() { FileFolder = FileFolder };
          }
  
          public FileViewModel GetFile(string fullname, string FileFolder, bool isCreate = false, string defaultContent = "")
          {
              var arr = fullname.Split('.');
              if (arr.Length == 2)
              {
                  return GetFile(arr[0], $".{arr[1]}", FileFolder, isCreate, defaultContent);
              }
              else
              {
                  return new FileViewModel() { FileFolder = FileFolder };
              }
          }
  
          public bool DeleteFile(string name, string extension, string FileFolder)
          {
              string folder = CommonHelper.GetFullPath(new string[] { SioConstants.Folder.UploadFolder, FileFolder });
              string fullPath = string.Format(@"{0}/{1}{2}", folder, name, extension);
  
              if (File.Exists(fullPath))
              {
                  CommonHelper.RemoveFile(fullPath);
              }
              return true;
          }
  
          public bool DeleteWebFile(string name, string extension, string FileFolder)
          {
              string fullPath = string.Format(@"{0}/{1}/{2}{3}", SioConstants.Folder.WebRootPath, FileFolder, name, extension);
  
              if (File.Exists(fullPath))
              {
                  CommonHelper.RemoveFile(fullPath);
              }
              return true;
          }
  
  
          public bool DeleteFile(string fullPath)
          {
              if (File.Exists(fullPath))
              {
                  CommonHelper.RemoveFile(fullPath);
              }
              return true;
          }
  
          public bool DeleteFolder(string folderPath)
          {
              if (Directory.Exists(folderPath))
              {
                  Directory.Delete(folderPath, true);
                  return true;
              }
              return false;
          }
  
          public bool EmptyFolder(string folderPath)
          {
              DeleteFolder(folderPath);
              CreateDirectoryIfNotExist(folderPath);
              return true;
          }
  
          public bool CopyDirectory(string srcPath, string desPath)
          {
              if (srcPath.ToLower() != desPath.ToLower() && Directory.Exists(srcPath))
              {
                  //Now Create all of the directories
                  foreach (string dirPath in Directory.GetDirectories(srcPath, "*", SearchOption.AllDirectories))
                  {
                      Directory.CreateDirectory(dirPath.Replace(srcPath, desPath));
                  }
  
                  //Copy all the files & Replaces any files with the same name
                  foreach (string newPath in Directory.GetFiles(srcPath, "*.*", SearchOption.AllDirectories))
                  {
                      File.Copy(newPath, newPath.Replace(srcPath, desPath), true);
                  }
  
                  return true;
              }
              return true;
          }
           public bool CopyWebDirectory(string srcPath, string desPath)
          {
              if (srcPath != desPath)
              {
                  //Now Create all of the directories
                  foreach (string dirPath in Directory.GetDirectories($"{SioConstants.Folder.WebRootPath}/{srcPath}", "*", SearchOption.AllDirectories))
                  {
                      Directory.CreateDirectory(dirPath.Replace(srcPath, desPath));
                  }
  
                  //Copy all the files & Replaces any files with the same name
                  foreach (string newPath in Directory.GetFiles($"{SioConstants.Folder.WebRootPath}/{srcPath}", "*.*", SearchOption.AllDirectories))
                  {
                      File.Copy(newPath, newPath.Replace(srcPath, desPath), true);
                  }
  
                  return true;
              }
              return true;
          }
  
          
          public void CreateDirectoryIfNotExist(string fullPath)
          {
              if (!string.IsNullOrEmpty(fullPath) && !Directory.Exists(fullPath))
              {
                  Directory.CreateDirectory(fullPath);
              }
          }
  
          public List<FileViewModel> GetUploadFiles(string folder)
          {
              string fullPath = CommonHelper.GetFullPath(new string[] { SioConstants.Folder.UploadFolder, folder });
  
              CreateDirectoryIfNotExist(fullPath);
  
              DirectoryInfo d = new DirectoryInfo(fullPath); //Assuming Test is your Folder
              FileInfo[] Files = d.GetFiles();
              List<FileViewModel> result = new List<FileViewModel>();
              foreach (var file in Files.OrderByDescending(f => f.CreationTimeUtc))
              {
                  using (StreamReader s = file.OpenText())
                  {
                      result.Add(new FileViewModel()
                      {
                          FileFolder = folder,
                          Filename = file.Name.Substring(0, file.Name.LastIndexOf('.')),
                          Extension = file.Extension,
                          Content = s.ReadToEnd()
                      });
                  }
              }
              return result;
          }
  
          public List<string> GetTopDirectories(string folder)
          {
              string fullPath = CommonHelper.GetFullPath(new string[]
              {
                  SioConstants.Folder.WebRootPath,
                  folder
              });
              List<string> result = new List<string>();
              if (Directory.Exists(fullPath))
              {
                  foreach (string dirPath in Directory.GetDirectories(fullPath, "*",
                      SearchOption.TopDirectoryOnly))
                  {
                      DirectoryInfo path = new DirectoryInfo(dirPath);
                      result.Add(path.Name);
                  }
              }
              return result;
          }
  
          public List<FileViewModel> GetTopFiles(string folder)
          {
              string fullPath = CommonHelper.GetFullPath(new string[]
               {
                  SioConstants.Folder.WebRootPath,
                  //SioConstants.Folder.FileFolder,
                  folder
               });
  
              string webPath = CommonHelper.GetFullPath(new string[]
               {
                  //SioConstants.Folder.FileFolder,
                  folder
               });
              List<FileViewModel> result = new List<FileViewModel>();
              if (Directory.Exists(fullPath))
              {
                  DirectoryInfo path = new DirectoryInfo(fullPath);
                  string folderName = path.Name;
  
                  var Files = path.GetFiles();
                  foreach (var file in Files.OrderByDescending(f => f.CreationTimeUtc))
                  {
                      result.Add(new FileViewModel()
                      {
                          FolderName = folderName,
                          FileFolder = webPath,
  
                          Filename = file.Name.Substring(0, file.Name.LastIndexOf('.') >= 0 ? file.Name.LastIndexOf('.') : 0),
                          Extension = file.Extension,
                          //Content = s.ReadToEnd()
                      });
                  }
              }
              return result;
          }
  
          public List<FileViewModel> GetFilesWithContent(string fullPath)
          {
              CreateDirectoryIfNotExist(fullPath);
  
              //DirectoryInfo d = new DirectoryInfo(fullPath); //Assuming Test is your Folder
              FileInfo[] Files;
              List<FileViewModel> result = new List<FileViewModel>();
              foreach (string dirPath in Directory.GetDirectories(fullPath, "*",
                  SearchOption.AllDirectories))
              {
                  DirectoryInfo path = new DirectoryInfo(dirPath);
                  string folderName = path.Name;
  
                  Files = path.GetFiles();
                  foreach (var file in Files.OrderByDescending(f => f.CreationTimeUtc))
                  {
                      using (StreamReader s = file.OpenText())
                      {
                          result.Add(new FileViewModel()
                          {
                              FolderName = folderName,
                              FileFolder = CommonHelper.GetFullPath(new string[] { fullPath, folderName }),
                              Filename = file.Name.Substring(0, file.Name.LastIndexOf('.')),
                              Extension = file.Extension,
                              Content = s.ReadToEnd()
                          });
                      }
                  }
              }
              return result;
          }
  
          public List<FileViewModel> GetFiles(string fullPath)
          {
              CreateDirectoryIfNotExist(fullPath);
  
              FileInfo[] Files;
  
gt:             List<FileViewModel> result = new List<FileViewModel>();