module PathScenariosGenerator

  def generate_get_path_scenarios_with_provider name, path, provider, &block
    concat %Q(
  @#{provider}
  Scenario: #{name}
    When I send GET '#{path}' query
    Then response should be '200'
    And the Content-Type header should include 'application/json'
)
    res = block.call if block_given?
    generate_401_406 name, "GET", path, nil, provider
  end

  def generate_get_path_scenarios name, path, &block
    concat %Q(
  Scenario: #{name}
    When I send GET '#{path}' query
    Then response should be '200'
    And the Content-Type header should include 'application/json'
)
    res = block.call if block_given?
    generate_401_406 name, "GET", path
  end

  def generate_mandatory_fields_validation method, name, path, body, mandatory_fields=[], provider=nil
    mandatory_fields.each do |field|
      types = [Array, Hash, String]
      val_class = body[field].class
      types.delete(val_class)
      # mongoid specification: [] and {} are valid values for String
     # invalid_value_code = val_class == String ? 422 : 400
      types.each do |t|
        value = t.new
        tmp_body = body.clone
        tmp_body[field] = value
        concat "\n  @#{provider}" if provider
        concat %Q(\n  Scenario: #{name} with invalid parameter '#{field}', value: '#{value}'
    When I send #{method.upcase} '#{path}' query with JSON body
    """
#{JSON.pretty_generate(tmp_body)}
    """
    Then response should be '400'
    And the Content-Type header should include 'application/json'
)
        tmp_body[field] = nil
        concat "\n  @#{provider}" if provider
        concat %Q(\n  Scenario: #{name} with invalid parameter '#{field}', value: null
    When I send #{method.upcase} '#{path}' query with JSON body
    """
#{JSON.pretty_generate(tmp_body)}
    """
    Then response should be '400'
    And the Content-Type header should include 'application/json'
)
        tmp_body.delete(field)
        concat "\n  @#{provider}" if provider
        concat %Q(\n  Scenario: #{name} without parameter '#{field}'
    When I send #{method.upcase} '#{path}' query with JSON body
    """
#{JSON.pretty_generate(tmp_body)}
    """
    Then response should be '400'
    And the Content-Type header should include 'application/json'
)
      end
    end
  end

  def generate_create_path_scenarios_without_401 name, path, body, mandatory_fields=[], provider=nil, &block
    generate_406 name, "POST", path, body, provider

    generate_mandatory_fields_validation "POST", name, path, body, mandatory_fields, provider

    concat "\n  @#{provider}" if provider
    concat %Q(\n  Scenario: #{name}
    When I send POST '#{path}' query with JSON body
    """
#{JSON.pretty_generate(body)}
    """
    Then response should be '201'
    And the Content-Type header should include 'application/json'
)
    res = block.call if block_given?
    concat "\n  @#{provider}" if provider
    concat %Q(\n  Scenario: #{name} (second time)
    When I send POST '#{path}' query with JSON body
    """
#{JSON.pretty_generate(body)}
    """
    Then response should be '422'
    And the Content-Type header should include 'application/json'
)
  end

  def generate_create_path_scenarios name, path, body, mandatory_fields=[], provider=nil, &block
    generate_401 name, "POST", path, provider
    generate_create_path_scenarios_without_401 name, path, body, mandatory_fields, provider, &block
  end

  def generate_401_406_415 name, method, path, body, provider=nil
    generate_401_406(name, method, path, body, provider)
    generate_415 name, method, path, body, provider
  end

  def generate_401_406 name, method, path, body=nil, provider=nil
    generate_406 name, method, path, body, provider
    generate_401 name, method, path, provider
  end

  def generate_401 name, method, path, provider=nil
    concat "\n  @#{provider}" unless provider.nil?
    concat %Q(\n  Scenario: #{name} with user without privileges
    When I send #{method} '#{path}' query with user without privileges
    Then response should be '401'
)
  end

  def generate_406 name, method, path, body=nil, provider=nil
    concat "\n  @#{provider}" unless provider.nil?
    if body.nil?
    concat %Q(\n  Scenario: #{name} with header 'Accept' value not 'application/json'
    When I send #{method} '#{path}' query with header 'Accept' value 'application/xml'
    Then response should be '406'
)
    else
    concat %Q(\n  Scenario: #{name} with header 'Accept' value not 'application/json'
    When I send #{method} '#{path}' query with JSON body with header 'Accept' value 'application/xml'
    """
#{JSON.pretty_generate(body)}
    """
    Then response should be '406'
)
    end
  end

  def generate_415 name, method, path, body, provider=nil
    concat "\n  @#{provider}" unless provider.nil?
    concat %Q(\n  Scenario: #{name} without header 'Content-Type'
    When I send #{method} '#{path}' query with JSON body without header 'Content-Type'
    """
#{JSON.pretty_generate(body)}
    """
    Then response should be '415'
)
  end

  def generate_delete_path_scenarios name, path, provider=nil, &block
    generate_401 name, "DELETE", path, provider
    generate_406 name, "DELETE", path, nil, provider

    concat "\n  @#{provider}" if provider
    concat %Q(\n  Scenario: #{name}
    When I send DELETE '#{path}' query
    Then response should be '200'
    And the Content-Type header should include 'application/json'
)
    res = block.call if block_given?

    concat "\n  @#{provider}" unless provider.nil?
    concat %Q(\n   Scenario: #{name} (second time)
    When I send DELETE '#{path}' query
    Then response should be '404'
    And the Content-Type header should include 'application/json'
    And the JSON response should be an object
)
  end

  def generate_update_path_scenarios name, path, body, provider=nil, &block
    generate_modify_path_scenarios "PUT", name, path, body, provider, &block
  end

  def generate_modify_path_scenarios method, name, path, body, provider=nil, &block
    generate_401 name, method.upcase, path, provider
    generate_406 name, method.upcase, path, body, provider

    concat "\n  @#{provider}" if provider
    concat %Q(\n  Scenario: #{name}
    When I send #{method.upcase} '#{path}' query with JSON body
    """
#{JSON.pretty_generate(body)}
    """
    Then response should be '200'
    And the Content-Type header should include 'application/json'
)
    res = block.call if block_given?
  end

end
