module GifterHub
  class ApiResource
    include Operations::Get
    attr_accessor :id, :opts, :attributes

    def initialize(id=nil, opts={})
      @id = id
      @opts = opts
      @values = {}
      @attributes = {}
    end

    def self.class_name
      self.name.split('::')[-1]
    end

    def self.resource_url
      if self == ApiResource
        raise NotImplementedError
      end
      "/api/#{CGI.escape(class_name.tableize)}"
    end

    def self.get(id, opts={})
      instance = self.new(id, opts)
      instance.refresh
      instance
    end

    def inspect
      JSON.pretty_generate(attributes)
    end

    def resource_url
      "#{self.class.resource_url}/#{CGI.escape(id)}"
    end

    def refresh
      response = request(:get, resource_url, opts)
      initialize_from(response, opts)
    end

    private

    # Convert hash key value pair to method
    def initialize_from(values, opts={})
      @opts = opts
      added = Set.new(values.keys - @values.keys)
      @attributes = values
      add_accessors(added, values)
      self
    end

    def add_accessors(keys, values)
      metaclass.instance_eval do
        keys.each do |k|
          define_method(k) { values[k] }

          if [FalseClass, TrueClass].include?(values[k].class)
            k_bool = :"#{k}?"
            define_method(k_bool) { values[k] }
          end
        end
      end
    end

    def metaclass
      class << self; self; end
    end
  end
end