require 'rocketamf_extensions/remote_gateway'

module Neopets::CustomPets
	GATEWAY_URL =
		Addressable::URI.parse(Rails.configuration.neopets_origin) +
		'/amfphp/gateway.php'
	GATEWAY = RocketAMFExtensions::RemoteGateway.new(GATEWAY_URL)
	CUSTOM_PET_SERVICE = GATEWAY.service('CustomPetService')
	PET_SERVICE = GATEWAY.service('PetService')

	class << self
		# NOTE: Ideally pet requests shouldn't take this long, but Neopets can be
		# slow sometimes! Since we're on the Falcon server, long timeouts shouldn't
		# slow down the rest of the request queue, like it used to be in the past.
		def fetch_viewer_data(name, timeout: 10)
			request = CUSTOM_PET_SERVICE.action('getViewerData').request([name])
			send_amfphp_request(request).tap do |data|
				if data[:custom_pet][:name].blank?
					raise PetNotFound, "Pet #{name.inspect} does not exist"
				end
			end
		end

		def fetch_metadata(name, timeout: 10)
			# If this is an image hash "pet name", it has no metadata.
			return nil if name.start_with?("@")

			request = PET_SERVICE.action('getPet').request([name])
			send_amfphp_request(request).tap do |data|
				if data[:name].blank?
					raise PetNotFound, "Pet #{name.inspect} does not exist"
				end
			end
		end

		# Given a pet's name, load its image hash, for use in `pets.neopets.com`
		# image URLs. (This corresponds to its current biology and items.)
		def fetch_image_hash(name, timeout: 10)
			# If this is an image hash "pet name", just take off the `@`!
			return name[1..] if name.start_with?("@")

			metadata = fetch_metadata(name, timeout:)
			metadata[:hash]
		end

		private

		# Send an AMFPHP request, re-raising errors as `DownloadError`.
		# Return the response body as a `HashWithIndifferentAccess`.
		def send_amfphp_request(request, timeout: 10)
			begin
				response_data = request.post(timeout: timeout, headers: {
					"User-Agent" => Rails.configuration.user_agent_for_neopets,
				})
			rescue RocketAMFExtensions::RemoteGateway::AMFError => e
				raise DownloadError, e.message
			rescue RocketAMFExtensions::RemoteGateway::ConnectionError => e
				raise DownloadError, e.message, e.backtrace
			end

			HashWithIndifferentAccess.new(response_data)
		end
	end

	class PetNotFound < RuntimeError;end
	class DownloadError < RuntimeError;end
end