class Kuroko2::Workflow::Node

def self.deregister(key)

def self.deregister(key)
  TASK_REGISTRY.delete(key)
end

def self.register(key: nil, klass:)

def self.register(key: nil, klass:)
  key ||= klass.to_s.demodulize.underscore.to_sym
  unless TASK_REGISTRY.has_key?(key)
    TASK_REGISTRY.store(key, klass)
  else
    Kuroko2.logger.warn("Unable to add '#{klass}' to task registry. '#{TASK_REGISTRY[key]}' is already registered.")
  end
end

def append_child(child)

def append_child(child)
  child.parent = self
  @children << child
end

def current_index

def current_index
  @_current_index = parent.children.index(self)
end

def execute(token)

def execute(token)
  Kuroko2.logger.debug { "(token #{token.uuid}) Execute #{@type} with option '#{@option}'." }
  @task_klass.new(self, token).execute.tap do |result|
    Kuroko2.logger.debug("(token #{token.uuid}) Result is '#{result}'.")
  end
end

def find(path)

def find(path)
  raise AssertionError, "path query('#{path}') is invalid." unless PATH_REGEXP === path
  query = path.split('/')
  query.shift # drop first empty string.
  traverse(query)
end

def initialize(type, option = nil)

def initialize(type, option = nil)
  @type       = type.to_sym
  @task_klass = TASK_REGISTRY.fetch(@type, nil)
  @option     = option.try(:strip)
  @parent     = nil
  @children   = []
  raise AssertionError, "`#{@type}` is not registered in task repository." unless @task_klass
end

def next(index = 0)

def next(index = 0)
  if (child = children[index])
    child
  else
    next_sibling
  end
end

def next_sibling

def next_sibling
  if parent
    parent.next(current_index + 1)
  else
    nil
  end
end

def path

def path
  if parent
    parent.path + "/#{current_index}-#{type}"
  else
    ''
  end
end

def to_script(indent = 0)

def to_script(indent = 0)
  "#{'  ' * indent}#{type}: #{option}\n" + children.map { |child| child.to_script(indent + 1) }.join
end

def traverse(query)

def traverse(query)
  return self if query.empty?
  first    = query.shift
  index, _ = first.split('-')
  @children[index.to_i].traverse(query)
end

def validate_all

def validate_all
  @task_klass.new(self, nil).validate
  @children.each do |child|
    child.validate_all
  end
end