# frozen_string_literal: true

require_relative 'abstract_handler'

module Hypertube
  module Core
    module Handler
      class LoadLibraryHandler < Hypertube::Core::Handler::AbstractHandler
        @@loaded_libraries = []

        def initialize
          @required_parameters_count = 1
        end

        def process(command)
          validate(command, @required_parameters_count, self.class.name)

          assembly_name = command.payload[0]

          # Normalize to absolute path
          expanded_path = File.expand_path(assembly_name)

          raise LoadError.new("Library not found: #{assembly_name}") unless File.exist?(expanded_path)

          normalized_path = normalize_path(expanded_path)

          if File.directory?(normalized_path)
            load_ruby_files_from_directory(normalized_path)
          else
            load_ruby_file(normalized_path)
          end

          0
        end

        def self.get_loaded_libraries
          @@loaded_libraries
        end

        private

        def load_ruby_files_from_directory(directory_path)
          pattern = File.join(directory_path, '**', '*.rb')
          Dir.glob(pattern).sort.each do |file_path|
            load_ruby_file(file_path)
          end
        end

        def load_ruby_file(file_path)
          normalized_file_path = normalize_path(file_path)
          return if library_already_loaded?(normalized_file_path)

          require normalized_file_path

          @@loaded_libraries << normalized_file_path
        end

        def normalize_path(path)
          File.realpath(path)
        rescue StandardError
          File.expand_path(path)
        end

        def library_already_loaded?(candidate_path)
          return true if @@loaded_libraries.include?(candidate_path)

          @@loaded_libraries.any? do |loaded_path|
            File.identical?(loaded_path, candidate_path)
          rescue StandardError
            false
          end
        end
      end
    end
  end
end
