# frozen_string_literal: true

require 'json'

module Engines
  module Sorbet
    class Extractor
      METRICS = %i[
        sorbet_number_of_sig_count
        sorbet_number_of_input_classes_total
        sorbet_number_of_input_sends_total
        sorbet_number_of_input_files
        sorbet_number_of_input_methods_total
        sorbet_number_of_input_modules_total

        sorbet_number_of_sigil_true
        sorbet_number_of_sigil_false
        sorbet_number_of_sigil_autogenerated
        sorbet_number_of_sigil_strong
        sorbet_number_of_sigil_strict
        sorbet_number_of_sigil_ignore
      ].freeze

      def initialize; end

      def call(provider)
        return unless requirements?

        metrics = METRICS.map do |metric|
          [metric, send(metric)]
        end.to_h

        provider.emit(metrics)
      end

      private

      def requirements?
        File.exist?('sorbet.output.json')
      end

      # NOTE: This output file must be created by an external command
      def sorbet
        @sorbet ||= JSON.parse(File.read('sorbet.output.json'))
      end

      def sorbet_metrics
        sorbet['metrics']
      end

      def find_metric(name, default = 0)
        match = sorbet_metrics.find do |metric|
          metric['name'] == name
        end

        return default if match.nil?

        match['value']
      end

      def sorbet_number_of_sig_count
        find_metric('codemetrics.types.sig.count')
      end

      def sorbet_number_of_input_classes_total
        find_metric('codemetrics.types.input.classes.total')
      end

      def sorbet_number_of_input_sends_total
        find_metric('codemetrics.types.input.sends.total')
      end

      def sorbet_number_of_input_files
        find_metric('codemetrics.types.input.files')
      end

      def sorbet_number_of_input_methods_total
        find_metric('codemetrics.types.input.methods.total')
      end

      def sorbet_number_of_input_modules_total
        find_metric('codemetrics.types.input.modules.total')
      end

      def sorbet_number_of_sigil_true
        find_metric('codemetrics.types.input.files.sigil.true')
      end

      def sorbet_number_of_sigil_false
        find_metric('codemetrics.types.input.files.sigil.false')
      end

      def sorbet_number_of_sigil_autogenerated
        find_metric('codemetrics.types.input.files.sigil.autogenerated')
      end

      def sorbet_number_of_sigil_strong
        find_metric('codemetrics.types.input.files.sigil.strong')
      end

      def sorbet_number_of_sigil_strict
        find_metric('codemetrics.types.input.files.sigil.strict')
      end

      def sorbet_number_of_sigil_ignore
        find_metric('codemetrics.types.input.files.sigil.ignore')
      end
    end
  end
end
