# frozen_string_literal: true

class Netdisco
  class Output
    # 类对象属性
    attr_reader :peers, :resolve, :poll_map

    # 对象初始化入口函数
    # 将邻居发现清单以及本地的轮询列表清单比对后,格式化输出相关数据
    def initialize(peers, poll_map)
      @peers    = peers
      @poll_map = poll_map
      @resolve  = false
    end

    # 动态方法
    def method_missing(name, *args)
      raise NoMethodError, "invalid method #{name} for #{inspect}:#{self.class}" unless name.match?(/to_.*/)
      output = File.basename name[3..-1]
      require_relative "output/" + output
      output = Netdisco::Output.const_get output.capitalize
      output.send :output, self
    end

    # 自动更新设备主机名,并更新解析状态
    # resolves ip addresses of peers and @peers keys
    # @return [void]
    def resolve!
      @resolve  = true
      new_peers = {}
      @peers.each do |host, peers|
        peers.each { |peer| peer.name }
        name            = DNS.getname host
        new_peers[name] = peers
      end
      @peers = new_peers
    end

    # 自动移除非探测名单范围内的设备
    # remove peers not matching to configured CIDR
    # @return [void]
    def clean!
      @peers.values.each do |peers|
        peers.delete_if { |peer| not @poll_map.include? peer.ip }
      end
    end

    # @return [Hash] of nodes found
    def to_h
      hash = {}
      @peers.each do |host, peers|
        array = []
        peers.each do |peer|
          array << peer.to_h
        end
        hash[host] = array
      end
      hash
    end

    # @return [Array] of nodes found
    def to_a
      nodes = []
      @peers.each do |host, peers|
        nodes << host
        peers.each do |peer|
          nodes << @resolve ? peer.name : peer.ip
        end
      end
      # 将 nodes 展开为属组并去重排序
      nodes.flatten.uniq
    end

    # @return [String] pretty print of hash
    def to_hash
      require "pp"
      out = ""
      PP.pp to_h, out
      out
    end

    # @return [String] yaml of hosts and peers found
    def to_yaml
      require "yaml"
      YAML.dump to_h
    end

    # @return [String] json of hosts and peers found
    def to_json
      require "json"
      JSON.pretty_generate to_h
    end
  end
end