class Lutaml::Cli::Uml::FindCommand

FindCommand finds elements by criteria

def self.add_options_to(thor_class, _method_name)

def self.add_options_to(thor_class, _method_name)
  thor_class.long_desc <<-DESC
  Find elements matching specific criteria.
  Examples:
    lutaml uml find model.lur --stereotype interface
    lutaml uml find model.lur --package ModelRoot::Core
    lutaml uml find model.lur --pattern "^Building.*"
  DESC
  thor_class.option :stereotype, type: :string,
                                 desc: "Filter by stereotype"
  thor_class.option :package, type: :string, desc: "Filter by package"
  thor_class.option :pattern, type: :string, desc: "Match name pattern"
  thor_class.option :format, type: :string, default: "text",
                             desc: "Output format (text|yaml|json)"
  thor_class.option :lazy, type: :boolean, default: false,
                           desc: "Use lazy loading"
end

def initialize(options = {})

def initialize(options = {})
  @options = options.transform_keys(&:to_sym)
end

def run(lur_path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity

rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
def run(lur_path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  validate_options!
  # Load the repository from the LUR file
  repo = load_repository(lur_path, lazy: options[:lazy])
  # Get results based on the filter type
  results = if options[:pattern] # e.g. "^Building.*"
              types = [options[:type] || :class]
              repo.search(options[:pattern], types: types)
            elsif options[:stereotype]
              repo.find_classes_by_stereotype(options[:stereotype])
            elsif options[:package]
              repo.classes_in_package(options[:package],
                                      recursive: false)
            else
              []
            end
  # Extract classes from the nested structure
  classes = case results
            when Array
              if results.length == 2 && results[0] == :classes
                results[1]  # Extract the actual classes array
              else
                results     # Assume it's already an array of classes
              end
            when NilClass
              []
            else
              [results]     # Wrap single result in array
            end
  if classes.nil? || classes.empty?
    filter_desc = if options[:pattern]
                    "pattern: #{options[:pattern]}"
                  elsif options[:stereotype]
                    "stereotype: #{options[:stereotype]}"
                  elsif options[:package]
                    "package: #{options[:package]}"
                  else
                    "criteria"
                  end
    puts "No elements found matching #{filter_desc}"
    return
  end
  output = classes.map do |cls|
    cls.is_a?(Lutaml::Uml::TopElement) ? cls.name : cls.to_s
  end
  # output result based on the format option
  case options[:format]
  when "json"
    puts output.to_json
  when "yaml"
    puts output.to_yaml
  else
    puts output.join("\n")
  end
rescue Thor::Error
  raise
rescue ArgumentError => e
  raise Thor::Error, e.message
rescue StandardError => e
  raise Thor::Error, "Find command failed: #{e.message}"
end

def validate_options!

def validate_options!
  # At least one filter option must be specified
  unless options[:pattern] || options[:stereotype] || options[:package]
    puts "Please specify at least one filter: " \
         "--pattern, --stereotype, or --package"
    raise Thor::Error,
          "Please specify at least one filter: " \
          "--pattern, --stereotype, or --package"
  end
end