module IDRAC::Power

def get_power_state

def get_power_state
  # Login to iDRAC if needed
  login unless @session_id
  
  # Get system information
  response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$select=PowerState")
  
  JSON.parse(handle_response(response))&.dig("PowerState")
end

def get_power_usage_watts

def get_power_usage_watts
  # Login to iDRAC if needed
  login unless @session_id
  
  response = authenticated_request(:get, "/redfish/v1/Chassis/System.Embedded.1/Power")
  
  JSON.parse(handle_response(response))&.dig("PowerControl", 0, "PowerConsumedWatts")&.to_f
end

def power_off(wait: true, kind: "ForceOff")

def power_off(wait: true, kind: "ForceOff")
  # Login to iDRAC if needed
  login unless @session_id
  
  puts "Powering off server...".light_cyan
  
  # Check current power state first
  current_state = get_power_state rescue "Unknown"
  if current_state == "Off"
    puts "Server is already powered OFF.".yellow
    return false
  end
  
  # Send power off command
  path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset"
  payload = { "ResetType" => kind }
  
  response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
  
  if response.status == 409
    puts "Server is already powered OFF.".yellow
  else
    handle_response(response)
  end
  
  # Wait for power state change if requested
  if wait
    success = wait_for_power_state(target_state: "Off", tries: 6)
    
    # If graceful shutdown failed, try force shutdown
    if !success && kind != "ForceOff"
      return power_off(wait: wait, kind: "ForceOff")
    end
  end
  
  return true
end

def power_on(wait: true)

def power_on(wait: true)
  # Login to iDRAC if needed
  login unless @session_id
  
  puts "Powering on server...".light_cyan
  
  # Check current power state first
  current_state = get_power_state rescue "Unknown"
  if current_state == "On"
    puts "Server is already powered ON.".yellow
    return false
  end
  
  # Send power on command (Reset with ResetType=On)
  path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset"
  payload = { "ResetType" => "On" }
  
  tries = 10
  while tries > 0
    response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
    
    case response.status
    when 200, 204
      puts "Server power on command sent successfully".green
      break
    when 409
      begin
        error_data = JSON.parse(response.body)
        if error_data["error"] && error_data["error"]["@Message.ExtendedInfo"] &&
           error_data["error"]["@Message.ExtendedInfo"].any? { |m| m["Message"] =~ /Server is already powered ON/ }
          puts "Server is already powered ON.".yellow
          return false
        else
          raise Error, "Failed to power on: #{error_data.inspect}"
        end
      rescue JSON::ParserError
        raise Error, "Failed to power on with status 409: #{response.body}"
      end
    when 500
      puts "[iDRAC 500] Server is busy...".red
      tries -= 1
      puts "Retrying... #{tries}/10".yellow if tries > 0
      sleep 10
    else
      raise Error, "Unknown response code #{response.status}: #{response.body}"
    end
  end
  
  raise Error, "Failed to power on after 10 retries" if tries <= 0
  
  # Wait for power state change if requested
  wait_for_power_state(target_state: "On", tries: 10) if wait
  
  return true
end

def reboot

def reboot
  # Login to iDRAC if needed
  login unless @session_id
  
  puts "Rebooting server...".light_cyan
  # Check current power state first
  current_state = get_power_state rescue "Unknown"
  if current_state == "Off"
    puts "Server is currently off, powering on instead of rebooting".yellow
    return power_on
  end
  
  # Send reboot command (Reset with ResetType=ForceRestart)
  path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset"
  payload = { "ResetType" => "ForceRestart" }
  
  response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
  
  if response.status >= 200 && response.status < 300
    puts "Server reboot command sent successfully".green
    return true
  elsif response.status == 409
    error_data = JSON.parse(response.body) rescue nil
    puts "Received conflict (409) error from iDRAC: #{error_data.inspect}"
    # Try gracefulRestart as an alternative
    puts "Trying GracefulRestart instead...".yellow
    payload = { "ResetType" => "GracefulRestart" }
    response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' })
    
    handle_response(response)
  else
    raise Error, "Failed to reboot server. Status code: #{response.status}"
  end
end

def wait_for_power_state(target_state:, tries: 6)

def wait_for_power_state(target_state:, tries: 6)
  retry_count = tries
  
  while retry_count > 0
    begin
      current_state = get_power_state
      
      return true if current_state == target_state
      
      puts "Waiting for power #{target_state == 'On' ? 'on' : 'off'}...".yellow
      puts "Current state: #{current_state}"
      retry_count -= 1
      sleep 8
    rescue => e
      puts "Error checking power state: #{e.message}".red
      retry_count -= 1
      sleep 5
    end
  end
  
  puts "Failed to reach power state #{target_state}".red
  return false
end