require "httparty"
require "hashie"
Hash.send :include, Hashie::Extensions

require "typeform/version"
require "typeform/form"
require "typeform/response"

module Typeform
  class << self
    # Allow Typeform.access_token = "..."
    def access_token=(access_token)
      Typeform.access_token = access_token
    end

    # Allow Typeform.base_uri = "..."
    def base_uri=(uri)
      Typeform.base_uri = uri
    end
  end

  # Represents a Typeform API error and contains specific data about the error.
  class TypeformError < StandardError
    attr_reader :data
    def initialize(data)
      @data = Hashie::Mash.new(data)
      super "The Typeform API responded with the following error - #{data}"
    end
  end

  class ClientError < StandardError; end
  class Forbidden < StandardError; end
  class ServerError < StandardError; end
  class BadRequest < TypeformError; end
  class Unauthorized < StandardError; end
  class NotFound < ClientError; end
  class Unavailable < StandardError; end

  class Typeform
    @@base_uri = "https://api.typeform.com"
    @@access_token = ""
    @@headers = {
      'User-Agent' => "typeform-rest-#{VERSION}",
      'Content-Type' => 'application/json; charset=utf-8',
      'Accept-Encoding' => 'gzip, deflate'
    }

    class << self
      # Get the API key (Typeform::Typeform.access_token)
      def access_token; @@access_token end

      # Set the API key
      def access_token=(access_token)
        return @@access_token unless access_token
        @@access_token = access_token
      end

      def get(*args)
        url = @@base_uri + args[0]
        response = HTTParty.get url, args[1]
        handle_response response
      end
      # No POST, PUT or DELETE for now - Read only Typeform API
      # def post(*args); handle_response super end
      # def put(*args); handle_response super end
      # def delete(*args); handle_response super end

      def handle_response(response) # :nodoc:
        case response.code
        when 400
          raise BadRequest.new response.parsed_response
        when 401
          raise Unauthorized.new
        when 403
          raise Forbidden.new response.parsed_response
        when 404
          raise NotFound.new response.body
        when 400...500
          raise ClientError.new response.parsed_response
        when 500...600
          raise ServerError.new response.body
        else
          response
        end
      end
    end
  end
end
