module Wicoris
  module Postman
    class Job
      attr_reader :logger

      def initialize(json_file, opts = {})
        @json_file = json_file
        @opts = opts
        @logger = opts[:logger]
      end

      # @returns [String] Path to actual letter
      def letter
        if not File.exists?(file)
          fail "Letter does not exist: #{file}"
        else
          file
        end
      end

      # Process the job
      def process
        deliver
        logger.info :message => 'Letter delivered :-D',
                    :patient => patient,
                    :job => @json_file
      rescue => e
        logger.error :message => 'Letter not delivered ;-(',
                     :patient => patient,
                     :reason => e.message,
                     :job => @json_file
        logger.debug e
      end

      # Remove the JSON file.
      def clear!
        FileUtils.rm(@json_file, :noop => (@opts[:noop] == true)) if json
      rescue JSON::ParserError
        logger.warn :message   => 'Refused to delete non-JSON file.',
                    :json_file => @json_file
      end

      # @returns [String] Patient's display name.
      def patient
        format('%s, %s (%s)',
               patient_last_name,
               patient_first_name,
               patient_date_of_birth)
      rescue
        'Unknown'
      end

      def to_s
        @json_file
      end

      private

      def deliver
        delivery_machine.new(self, @opts).run
      end

      # How we gonna deliver the letter?
      def delivery_machine
        # NOTE: `Object#type` is an existing method in Ruby 1.8.7, therefore we
        # have to fetch the attribute from the JSON hash.
        case json['type']
        when 'fax'  then FaxMachine
        when 'copy' then Copier
        # TODO: Handle unknown case!
        #else
        #  ...
        end
      end

      # Parse and return the JSON.
      # @returns [Hash] Cached JSON.
      def json
        @json ||= JSON.parse(json_file_content)
      end

      # FileMaker creates JSON files with Mac OS Roman file encoding.
      # We have to convert it to UTF-8 in order to avoid cryptic symbols.
      #
      # @returns [String] UTF-8 encoded file content.
      def json_file_content
        Iconv.conv('UTF-8', 'MacRoman', File.read(@json_file))
      end

      # Provide convenient methods for accessing JSON attributes.
      def method_missing(id,*args,&block)
        json.key?(id.to_s) ? json[id.to_s] : super
      end
    end
  end
end
