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

namespace Rokojori.Tools
{  
  public class BlenderResponse
  {
    public int exitCode;
    public string rawFileName;
    public string rawArguments;
    public string rawResponse;
  }

  public class Blender
  {
    static string _path = "blender" ;

    public static string path
    {
      get => _path;

      set 
      {
        _path = value;
      }
    }

    public static async Task<BlenderResponse> RunPython( string pythonPath, List<string> args, string workingDirectory = null )
    {
      var pythonArgs = new List<string>();

      pythonArgs.Add( "--background " );
      pythonArgs.Add( "--python " + pythonPath + " ");
      pythonArgs.Add( "-- " );

      pythonArgs.Add( args.Join( " " ) );

      var response = await Run( pythonArgs, workingDirectory );

      return response;
    }

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

      var joinedArgs = args.Join( " ");
      response.rawArguments = joinedArgs;
      response.rawFileName = _path;
      

      var process = new Process
      {
        StartInfo = new ProcessStartInfo
        {
          FileName = _path,
          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();

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

      // await Task.WhenAll( outputTask, errorTask );

      await process.WaitForExitAsync();

      
      response.exitCode = process.ExitCode;

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

      return response;
    }
  }
}

#endif