require "json"
require "exceptions/parser_error"
require "exceptions/validation_error"

module Devops
  module API3
    module ParserHelpers

      def create_object_from_json_body type=Hash, empty_body=false
        json = request.body.read.strip
        return nil if json.empty? and empty_body
        @body_json = begin
          ::JSON.parse(json)
        rescue ::JSON::ParserError => e
          DevopsLogger.logger.error e.message
          raise Devops::Exception::ParserError.new("Invalid JSON: #{e.message}")
        end
        raise Devops::Exception::ParserError.new("Invalid JSON, it should be an #{type == Array ? "array" : "object"}") unless @body_json.is_a?(type)
        @body_json
      end

      def check_provider provider
        list = ::Provider.providers
        raise Devops::Exception::ValidationError.new("Invalid provider '#{provider}', available providers: '#{list.join("', '")}'") unless list.include?(provider)
      end

      def check_string val, msg, _nil=false, empty=false
        check_param val, String, msg, _nil, empty
      end

      def check_boolean val, msg
        begin
          check_param val, TrueClass, msg, false, true
        rescue
          check_param val, FalseClass, msg, false, true
        end
      end

      def check_array val, msg, vals_type=String, _nil=false, empty=false
        check_param val, Array, msg, _nil, empty
        val.each {|v| raise Devops::Exception::ValidationError.new(msg) unless v.is_a?(vals_type)} unless val.nil?
        val
      end

      def check_filename file_name, not_string_msg, json_resp=true
        check_string file_name, not_string_msg
        r = Regexp.new("^[\\w _\\-.]{1,255}$", Regexp::IGNORECASE)
        if r.match(file_name).nil?
          msg = "Invalid file name '#{file_name}'. Expected name with 'a'-'z', '0'-'9', ' ', '_', '-', '.' symbols with length greate then 0 and less then 256 "
          raise Devops::Exception::ValidationError.new(msg, json_resp)
=begin
          if json_resp
            halt_response(msg)
          else
            halt(400, msg)
          end
=end
        end
        file_name
      end

      def check_param val, type, msg, _nil=false, empty=false
        if val.nil?
          if _nil
            return val
          else
            raise Devops::Exception::ParserError.new(msg)
          end
        end
        if val.is_a?(type)
          raise Devops::Exception::ParserError.new(msg) if !empty && val.empty?
          val
        else
          raise Devops::Exception::ParserError.new(msg)
        end
      end

    end
  end
end

