context: using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Globalization;
  using System.IO;
  using System.Linq;
  using System.Reflection;
  using System.Text;
  using System.Text.RegularExpressions;
  using LibGit2Sharp.Core;
  using Xunit;
  
  namespace LibGit2Sharp.Tests.TestHelpers
  {
      public class BaseFixture : IPostTestDirectoryRemover, IDisposable
      {
          private readonly List<string> directories = new List<string>();
  
  #if LEAKS_IDENTIFYING
          public BaseFixture()
          {
              LeaksContainer.Clear();
          }
  #endif
  
          static BaseFixture()
          {
              // Do the set up in the static ctor so it only happens once
              SetUpTestEnvironment();
          }
  
          public static string BareTestRepoPath { get; private set; }
          public static string StandardTestRepoWorkingDirPath { get; private set; }
          public static string StandardTestRepoPath { get; private set; }
          public static string ShallowTestRepoPath { get; private set; }
          public static string MergedTestRepoWorkingDirPath { get; private set; }
          public static string MergeTestRepoWorkingDirPath { get; private set; }
          public static string MergeRenamesTestRepoWorkingDirPath { get; private set; }
          public static string RevertTestRepoWorkingDirPath { get; private set; }
          public static string SubmoduleTestRepoWorkingDirPath { get; private set; }
          private static string SubmoduleTargetTestRepoWorkingDirPath { get; set; }
          private static string AssumeUnchangedRepoWorkingDirPath { get; set; }
          public static string SubmoduleSmallTestRepoWorkingDirPath { get; set; }
  
          public static DirectoryInfo ResourcesDirectory { get; private set; }
  
          public static bool IsFileSystemCaseSensitive { get; private set; }
  
          protected static DateTimeOffset TruncateSubSeconds(DateTimeOffset dto)
          {
              int seconds = dto.ToSecondsSinceEpoch();
              return Epoch.ToDateTimeOffset(seconds, (int)dto.Offset.TotalMinutes);
          }
  
          private static void SetUpTestEnvironment()
          {
              IsFileSystemCaseSensitive = IsFileSystemCaseSensitiveInternal();
  
              string initialAssemblyParentFolder = Directory.GetParent(new Uri(typeof(BaseFixture).Assembly.EscapedCodeBase).LocalPath).FullName;
  
              const string sourceRelativePath = @"../../Resources";
              ResourcesDirectory = new DirectoryInfo(Path.Combine(initialAssemblyParentFolder, sourceRelativePath));
  
              // Setup standard paths to our test repositories
              BareTestRepoPath = Path.Combine(sourceRelativePath, "testrepo.git");
              StandardTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "testrepo_wd");
              StandardTestRepoPath = Path.Combine(StandardTestRepoWorkingDirPath, "dot_git");
              ShallowTestRepoPath = Path.Combine(sourceRelativePath, "shallow.git");
              MergedTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "mergedrepo_wd");
              MergeRenamesTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "mergerenames_wd");
              MergeTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "merge_testrepo_wd");
              RevertTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "revert_testrepo_wd");
              SubmoduleTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "submodule_wd");
              SubmoduleTargetTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "submodule_target_wd");
              AssumeUnchangedRepoWorkingDirPath = Path.Combine(sourceRelativePath, "assume_unchanged_wd");
              SubmoduleSmallTestRepoWorkingDirPath = Path.Combine(sourceRelativePath, "submodule_small_wd");
  
              CleanupTestReposOlderThan(TimeSpan.FromMinutes(15));
          }
  
          private static void CleanupTestReposOlderThan(TimeSpan olderThan)
          {
              var oldTestRepos = new DirectoryInfo(Constants.TemporaryReposPath)
                  .EnumerateDirectories()
                  .Where(di => di.CreationTimeUtc < DateTimeOffset.Now.Subtract(olderThan))
                  .Select(di => di.FullName);
  
              foreach (var dir in oldTestRepos)
              {
                  DirectoryHelper.DeleteDirectory(dir);
              }
          }
  
          private static bool IsFileSystemCaseSensitiveInternal()
          {
              var mixedPath = Path.Combine(Constants.TemporaryReposPath, "mIxEdCase-" + Path.GetRandomFileName());
  
              if (Directory.Exists(mixedPath))
              {
                  Directory.Delete(mixedPath);
              }
  
              Directory.CreateDirectory(mixedPath);
              bool isInsensitive = Directory.Exists(mixedPath.ToLowerInvariant());
  
              Directory.Delete(mixedPath);
  
              return !isInsensitive;
          }
  
          protected void CreateCorruptedDeadBeefHead(string repoPath)
          {
              const string deadbeef = "deadbeef";
              string headPath = string.Format("refs/heads/{0}", deadbeef);
  
              Touch(repoPath, headPath, string.Format("{0}{0}{0}{0}{0}\n", deadbeef));
          }
  
          protected SelfCleaningDirectory BuildSelfCleaningDirectory()
          {
              return new SelfCleaningDirectory(this);
          }
  
          protected SelfCleaningDirectory BuildSelfCleaningDirectory(string path)
          {
              return new SelfCleaningDirectory(this, path);
          }
  
          protected string SandboxBareTestRepo()
          {
              return Sandbox(BareTestRepoPath);
          }
  
          protected string SandboxStandardTestRepo()
          {
              return Sandbox(StandardTestRepoWorkingDirPath);
          }
  
          protected string SandboxMergedTestRepo()
          {
              return Sandbox(MergedTestRepoWorkingDirPath);
          }
  
          protected string SandboxStandardTestRepoGitDir()
          {
              return Sandbox(Path.Combine(StandardTestRepoWorkingDirPath));
          }
  
          protected string SandboxMergeTestRepo()
          {
              return Sandbox(MergeTestRepoWorkingDirPath);
          }
  
          protected string SandboxRevertTestRepo()
          {
              return Sandbox(RevertTestRepoWorkingDirPath);
          }
  
          public string SandboxSubmoduleTestRepo()
          {
              return Sandbox(SubmoduleTestRepoWorkingDirPath, SubmoduleTargetTestRepoWorkingDirPath);
          }
  
          public string SandboxAssumeUnchangedTestRepo()
          {
              return Sandbox(AssumeUnchangedRepoWorkingDirPath);
          }
  
          public string SandboxSubmoduleSmallTestRepo()
          {
              var path = Sandbox(SubmoduleSmallTestRepoWorkingDirPath, SubmoduleTargetTestRepoWorkingDirPath);
              Directory.CreateDirectory(Path.Combine(path, "submodule_target_wd"));
  
              return path;
          }
  
          protected string Sandbox(string sourceDirectoryPath, params string[] additionalSourcePaths)
          {
              var scd = BuildSelfCleaningDirectory();
              var source = new DirectoryInfo(sourceDirectoryPath);
  
              var clonePath = Path.Combine(scd.DirectoryPath, source.Name);
              DirectoryHelper.CopyFilesRecursively(source, new DirectoryInfo(clonePath));
  
              foreach (var additionalPath in additionalSourcePaths)
              {
                  var additional = new DirectoryInfo(additionalPath);
                  var targetForAdditional = Path.Combine(scd.DirectoryPath, additional.Name);
  
                  DirectoryHelper.CopyFilesRecursively(additional, new DirectoryInfo(targetForAdditional));
              }
  
              return clonePath;
          }
  
          protected string InitNewRepository(bool isBare = false)
          {
              SelfCleaningDirectory scd = BuildSelfCleaningDirectory();
  
              return Repository.Init(scd.DirectoryPath, isBare);
          }
  
          protected Repository InitIsolatedRepository(string path = null, bool isBare = false, RepositoryOptions options = null)
          {
              path = path ?? InitNewRepository(isBare);
              options = BuildFakeConfigs(BuildSelfCleaningDirectory(), options);
  
  
gt:             return new Repository(path, options);