import {CoreWalker} from "../../../core/Walker";
import {DecomposedPath as DecomposedPath2} from "../../../core/DecomposedPath";
import {MethodDependency as MethodDependency2} from "../MethodDependency";
import {Poly as Poly2} from "../../Poly";
import {CoreType} from "../../../core/Type";
export class BaseMethod {
  constructor(param) {
    this.param = param;
    this._require_dependency = false;
  }
  require_dependency() {
    return this._require_dependency;
  }
  node() {
    return this._node = this._node || this.param.node;
  }
  static required_arguments() {
    console.warn("Expression.Method._Base.required_arguments virtual method call. Please override");
    return [];
  }
  static optional_arguments() {
    return [];
  }
  static min_allowed_arguments_count() {
    return this.required_arguments().length;
  }
  static max_allowed_arguments_count() {
    return this.min_allowed_arguments_count() + this.optional_arguments().length;
  }
  static allowed_arguments_count(count) {
    return count >= this.min_allowed_arguments_count() && count <= this.max_allowed_arguments_count();
  }
  process_arguments(args) {
    throw "Expression.Method._Base.process_arguments virtual method call. Please override";
  }
  async get_referenced_node_container(index_or_path) {
    const referenced_node = this.get_referenced_node(index_or_path);
    if (referenced_node) {
      let container;
      if (referenced_node.isDirty()) {
        container = await referenced_node.requestContainer();
      } else {
        container = referenced_node.container_controller.container;
      }
      if (container) {
        const core_group = container.coreContent();
        if (core_group) {
          return container;
        }
      }
      throw `referenced node invalid: ${referenced_node.fullPath()}`;
    } else {
      throw `invalid input (${index_or_path})`;
    }
  }
  get_referenced_param(path, decomposed_path) {
    const node = this.node();
    if (node) {
      return CoreWalker.find_param(node, path, decomposed_path);
    }
    return null;
  }
  find_referenced_graph_node(index_or_path, decomposed_path) {
    const is_index = CoreType.isNumber(index_or_path);
    if (is_index) {
      const index = index_or_path;
      const node = this.node();
      if (node) {
        const input_graph_node = node.io.inputs.input_graph_node(index);
        return input_graph_node;
      }
    } else {
      const path = index_or_path;
      return this.get_referenced_node(path, decomposed_path);
    }
    return null;
  }
  get_referenced_node(index_or_path, decomposed_path) {
    let node = null;
    const current_node = this.node();
    if (CoreType.isString(index_or_path)) {
      if (current_node) {
        const path = index_or_path;
        node = CoreWalker.find_node(current_node, path, decomposed_path);
      }
    } else {
      if (current_node) {
        const index = index_or_path;
        node = current_node.io.inputs.input(index);
      }
    }
    return node || null;
  }
  find_dependency(args) {
    return null;
  }
  create_dependency_from_index_or_path(index_or_path) {
    const decomposed_path = new DecomposedPath2();
    const node = this.find_referenced_graph_node(index_or_path, decomposed_path);
    if (node) {
      return this.create_dependency(node, index_or_path, decomposed_path);
    } else {
      Poly2.warn("node not found for path", index_or_path);
    }
    return null;
  }
  create_dependency(node, index_or_path, decomposed_path) {
    const dependency = MethodDependency2.create(this.param, index_or_path, node, decomposed_path);
    return dependency;
  }
}
