
using Godot;

using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Rokojori.DocGenerator
{
  public class DocCommentEntry
  {
    public string type;
    public string name;
    public string doc;
  }

  public class DocComments
  { 
    public Regex commentStartOld = new Regex( "\\/\\*\\*\\s*<\\s*summary\\s+for\\s*=\\s*\"\\s*(\\w+)\\s+(\\w+)\\s*\"" );
    public Regex commentStart = 

      RegexBuilder.Create()
      [ "/**" ]._[ "<" ]._[ "summary" ].__[ "for" ]._[ "=" ]._[ "\"" ]._.Word.__.Word._[ "\"" ]
      .ToRegex();


    public string classInfo = "class";
    public string fieldInfo = "field";
    public string methodInfo = "method";
    public List<DocCommentEntry> entries = new List<DocCommentEntry>();

    

    public void Grab( string data )
    {
      var lexEvents = CSharpLexer.Lex( data );

      //RJLog.Log( "Num lex events:", lexEvents.Count );
      lexEvents.ForEach(
        ( le )=>
        {
          if ( ! LexerMatcherLibrary.MultiLineCommentMatcher.Matches( le ) )
          {
            return;
          }

          var match = le.match;

          
          if ( ! commentStart.IsMatch( match ) )
          {
            Regex isStartPartially = new Regex( "/\\*\\*\\s*<\\s*summary\\s*" );

            //RJLog.Log( "Not doc Comment:", isStartPartially.IsMatch( match ), match );
            return;
          } 

          var result = commentStart.Matches( match );

          var type = result[ 0 ].Groups[ 1 ].Value;
          var name = result[ 0 ].Groups[ 2 ].Value;

          var bodyStart = match.IndexOf( ">" ) + 1;
          var bodyEnd   = match.LastIndexOf( "<" );
          var body = match.Substring( bodyStart, bodyEnd - bodyStart );
          
          var entry = new DocCommentEntry();
          entry.name = name;
          entry.type = type;
          entry.doc  = body;

          entries.Add( entry );

          // RJLog.Log( "Doc Comment:", entry.type, entry.name, ">>\n", entry.doc );

        }
      );
    }

    public string FindDoc( string type, string name )
    {
      var e = entries.Find( e => e.type == type && e.name == name );

      return e == null ? null : e.doc;
    }
  }
}