#!/usr/bin/ruby.ruby3.4

require 'rubygems'
require 'json'

class Line
  attr_accessor :line, :lines, :parent

  def initialize(line)
    self.line = line
    self.lines = []
  end

  def add(line)
    return if line.nil?
    return unless line.parent.nil?
    return unless check_up(line)

    line.parent = self
    lines << line
  end

  def check_up(line)
    return false if self == line
    return true unless parent

    parent.check_up(line)
  end
end

def log_line(file, d, prefix = '')
  file.write prefix + d.line.inspect
  d.lines.each do |l|
    log_line(file, l, "#{prefix}  ")
  end
end

filename = ARGV[0]
file = File.new(filename, 'r')
ids = {}
file.each_line do |line|
  d = JSON.parse(line)
  ids[d['_id']] = Line.new(d)
end
file.close
File.delete(file.path)
file = File.new(filename, 'w')

array_n1_n2_n3_block_scope_shared = %w[n1 n2 n3 block scope shared]

ids.each do |_, d|
  type = d.line['type'] || ''
  if d.line['data']
    if ['varmap', type == 'hash'].include?(type)
      d.line['data'].each do |key, value|
        d.add(ids[key])
        d.add(ids[value])
      end
    end
    if type == 'array'
      d.line['data'].each do |v|
        d.add(ids[v])
      end
    end
  end
  if type == 'scope' && d.line['variables']
    d.line['variables'].each do |key, value|
      d.add(ids[key])
      d.add(ids[value])
    end
  end
  if type == 'class' && d.line['methods']
    d.line['methods'].each do |key, value|
      d.add(ids[key])
      d.add(ids[value])
    end
  end
  if type == 'object' && d.line['ivars']
    d.line['ivars'].each do |key, value|
      d.add(ids[key])
      d.add(ids[value])
    end
  end
  array_n1_n2_n3_block_scope_shared.each do |key|
    d.add(ids[d.line[key]]) if d.line.key?(key)
  end
end
ids.each_value do |d|
  next unless d.parent.nil?

  log_line(file, d)
end
file.close
