#!/usr/bin/env ruby
# control.rb

require_relative '../lib/agent99'

class Control < Agent99::Base
  # this information is made available when the agent
  # registers with the central registry service.  It is
  # made available during the discovery process.
  #
  def info
    {
      name:             self.class.to_s,
      type:             :hybrid,
      capabilities:     ['control', 'headquarters', 'secret underground base'],
      # request_schema:   ControlRequest.schema,
      # response_schema:  {}, # Agent99::RESPONSE.schema
      # control_schema:   {}, # Agent99::CONTROL.schema
      # error_schema:     {}, # Agent99::ERROR.schema
    }
  end

  attr_accessor :statuses

  def init
    @agents = @registry_client.fetch_all_agents
    @statuses = {}
  end


  def send_control_message(message:, payload: {})
    @agents.each do |agent|
      response = @message_client.publish(
        header: {
          to_uuid: agent[:uuid],
          from_uuid: @id,
          event_uuid: SecureRandom.uuid,
          type: 'control',
          timestamp: Agent99::Timestamp.new.to_i
        },
        action: message,
        payload: payload
      )
      puts "Sent #{message} to #{agent[:name]}: #{response[:success] ? 'Success' : 'Failed'}"
    end
  end


  def pause_all
    send_control_message(message: 'pause')
  end


  def resume_all
    send_control_message(message: 'resume')
  end


  def stop_all
    send_control_message(message: 'shutdown')
  end

  def get_all_status
    @statuses.clear  # Reset statuses before new request
    
    @agents.each do |agent|
      @message_client.publish(
        header: {
          to_uuid:    agent[:uuid],
          from_uuid:  @id,
          event_uuid: SecureRandom.uuid,
          type:       'control',
          timestamp:  Agent99::Timestamp.new.to_i
        },
        action: 'status'
      )
    end

    # Wait for responses (with timeout)
    sleep 2  # Give agents time to respond
    @statuses
  end

  def receive_response
    if payload[:action] == 'response' && payload[:data][:type] == 'status'
      agent_name = payload[:header][:from_uuid]
      @statuses[agent_name] = payload[:data]
      logger.info "Received status from #{agent_name}: #{payload[:data]}"
    elsif payload[:action] == 'status' && payload[:header][:from_uuid] == @id
      # Handle our own status request
      handle_status_request
    end
  end


end


if __FILE__ == $PROGRAM_NAME
  control = Control.new
  
  # Start the message processing in a separate thread
  dispatcher_thread = Thread.new do
    control.run
  end

  # UI thread
  begin
    loop do
      puts "\n1. Pause all agents"
      puts "2. Resume all agents"
      puts "3. Stop all agents"
      puts "4. Get all agents status"
      puts "5. Exit"
      print "\nEnter your choice: "
      
      choice = gets.chomp.to_i

      case choice
      when 1
        control.pause_all
      when 2
        control.resume_all
      when 3
        control.stop_all
      when 4
        statuses = control.get_all_status
        sleep 2 # Give time for responses to arrive
        puts JSON.pretty_generate(control.statuses)
      when 5
        puts "Exiting..."
        Thread.exit
        break
      else
        puts "Invalid choice. Please try again."
      end
    end
  rescue Interrupt
    puts "\nShutting down..."
  ensure
    dispatcher_thread.exit
    control.fini
  end
end

