#if TOOLS
using Godot;
using Rokojori;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;

namespace Rokojori.Tools
{  
  public class GitResponse
  {
    public string rawResponse;
    public int exitCode;
  }

  public class Git 
  {
    public static async Task<System.DateTimeOffset?> GetFileChangedTime( string path )
    {
      var arguments = new List<string>()
      {
        "log -1 --format=\"%ct\" -- " + path.EscapeAsPathForCommandLine()
      };

      var response = await Run( arguments, RegexUtility.ParentPath( path ) );

      if ( response.exitCode != 0 )
      {
        return null;
      }

      try
      {
        var time = System.DateTimeOffset.FromUnixTimeSeconds( response.rawResponse.ToLong() );
        return time;
      }
      catch( System.Exception e ) 
      {
        RJLog.Error( e );
      }

      return null;
    }

    public static async Task<bool> IsFileNewerThan( string path, System.DateTimeOffset time )
    {
      var _fileChangedTime = await GetFileChangedTime( path );

      if ( _fileChangedTime == null )
      {
        return false;
      }

      var fileChangedTime = (DateTimeOffset) _fileChangedTime;


      return fileChangedTime.IsNewerThan( time );


    }

    public static async Task<GitResponse> Run( List<string> arguments, string workingDirectory = null )
    {
      var response = new GitResponse();

      var joinedArgs = arguments.Join( " ");

      RJLog.Log( "GIT", joinedArgs );

      var process = new Process
      {
        StartInfo = new ProcessStartInfo
        {
          FileName = "git",
          Arguments = joinedArgs,
          RedirectStandardOutput = true,
          RedirectStandardError = true,
          UseShellExecute = false,
          CreateNoWindow = true
        }
        
      };
      
      if ( workingDirectory != null )
      {
        process.StartInfo.WorkingDirectory = workingDirectory;
      }
      
      process.Start();

      var outputResult = new List<string>();
      var errorResult = new List<string>();

      process.OutputDataReceived += (sender, e) =>
      {
        if ( e.Data == null )
        {
          return;
        }
        
        RJLog.Log( e.Data );
        outputResult.Add( e.Data );
      };

      process.ErrorDataReceived += (sender, e) =>
      {
        if ( e.Data == null )
        {
          return;
        }

        RJLog.Error( e.Data );
        errorResult.Add( e.Data );
      };

      process.BeginOutputReadLine();
      process.BeginErrorReadLine();


      await process.WaitForExitAsync();

      
      response.exitCode = process.ExitCode;

      if ( process.ExitCode == 0 )
      {
        response.rawResponse = outputResult.Join( "" );
      }
      else
      {
        response.rawResponse = errorResult.Join( "" );
      }

      return response;
    }

    public static async Task<GitResponse> GetStatus( string path )
    {
      var process = new Process
      {
        StartInfo = new ProcessStartInfo
        {
          FileName = "git",
          Arguments = "status",
          RedirectStandardOutput = true,
          RedirectStandardError = true,
          UseShellExecute = false,
          CreateNoWindow = true,
          WorkingDirectory = path
        }
      };

      process.Start();

      var outputTask = process.StandardOutput.ReadToEndAsync();
      var errorTask  = process.StandardError.ReadToEndAsync();

      await Task.WhenAll( outputTask, errorTask );

      await process.WaitForExitAsync();

      var response = new GitResponse();
      response.exitCode = process.ExitCode;

      if ( process.ExitCode == 0 )
      {
        response.rawResponse = outputTask.Result;
      }
      else
      {
        response.rawResponse = errorTask.Result;
      }

      return response;
    }
  }

}

#endif