using Godot;

using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Reflection;

namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public partial class DebugAction:SequenceAction
  {
    protected const string name = "Run";


    protected List<DebugMessage> _messages = [];

    [Export]
    public DebugMessage[] messages = [];
    
    public void ClearMessages()
    {
      _messages.Clear();
      messages = [];
    }

    public void FinishMessages()
    {
      messages = _messages.ToArray();
    }

    [Export(PropertyHint.MultilineText)]
    public string status = "";


    public virtual void UpdateStatus( string status)
    {
      this.status = RJLog.Stringify(
        status + ( status == "" ? "" : "," ),  
         "Errors:", 
          _messages.FindAll( m => m.type == MessageType.Error ).Count + ",", 
        
        "Warnings:",
           _messages.FindAll( m => m.type == MessageType.Warning ).Count 
      );
    }

    [ExportToolButton( name )]
    public Callable RunButton => Callable.From(
      ()=>
      {
        Trigger( this );
      }
    );

    void AddMessage( MessageType type, Node n, params object[] messages )
    {
      var msg = new DebugMessage();
      msg.type = type;
      msg.node = n.GetPath();
      msg.content =  HierarchyName.Of( n ) + ":" + RJLog.Stringify( messages );       

      _messages.Add( msg );
    }

    void AddMessage( MessageType type, params object[] messages )
    {
      var msg = new DebugMessage();
      msg.type = type;
      msg.content =  RJLog.Stringify( messages );       

      _messages.Add( msg );
    }

    public void Verbose( Node n, params object[] messages )
    {
      AddMessage( MessageType.Verbose, n, messages );
    }

    public void Verbose( params object[] messages )
    {
      AddMessage( MessageType.Verbose, messages );
    }


    public void Info( Node n, params object[] messages )
    {
      AddMessage( MessageType.Info, n, messages );
    }

    public void Error( Node n, params object[] messages )
    {
      AddMessage( MessageType.Error, n, messages );
    }

    public void Warning( Node n, params object[] messages )
    {
      AddMessage( MessageType.Warning, n, messages );
    }
  }
}