# Copyright (c) 2023 Yuki Kimoto
# MIT License

class Runtime : pointer {
  use Env;
  use Stack;
  
  # Instance Methods
  native method get_basic_type_names : string[] ();
  
  native method get_basic_type_parent_name : string ($basic_type_name : string);
  
  method get_method_names : string[] ($basic_type_name : string, $options : object[] = undef) {
    
    my $native_flag = 0;
    my $precompile_flag = 0;
    my $enum_flag = 0;
    if ($options) {
      for (my $i = 0; $i < @$options; $i += 2) {
        my $key = (string)$options->[$i];
        my $value = $options->[$i + 1];
        
        if ($key eq "native") {
          $native_flag = (int)$value;
        }
        elsif ($key eq "precompile") {
          $precompile_flag = (int)$value;
        }
        elsif ($key eq "enum") {
          $enum_flag = (int)$value;
        }
      }
    }
    
    my $method_names = $self->_get_method_names($basic_type_name, $native_flag, $precompile_flag, $enum_flag);
    
    return $method_names;
  }
  
  private native method _get_method_names : string[] ($basic_type_name : string, $native_flag : int, $precompile_flag : int, $enum_flag : int);
  
  native method get_module_file : string ($basic_type_name : string);
  
  native method build_precompile_module_source : string ($basic_type_name : string);
  
  native method get_basic_type_anon_basic_type_names : string[] ($basic_type_name : string);
  
  native method get_method_is_class_method : int ($basic_type_name : string, $method_name : string);
  
  native method build_precompile_method_source : string ($basic_type_name : string, $method_name : string);
  
  native method get_native_method_address : Address ($basic_type_name : string, $method_name : string);
  
  native method set_native_method_address : string ($basic_type_name : string, $method_name : string, $address : Address);
  
  native method get_precompile_method_address : Address ($basic_type_name : string, $method_name : string);
  
  native method set_precompile_method_address : string ($basic_type_name : string, $method_name : string, $address : Address);
  
  native method DESTROY : void ();
}