class Gherkin::Pickles::Compiler

def compile(gherkin_document, source)

def compile(gherkin_document, source)
  pickles = []
  return pickles unless gherkin_document.feature
  feature = gherkin_document.feature
  language = feature.language
  tags = feature.tags
  compile_feature(pickles, language, tags, feature, source)
  pickles
end

def compile_feature(pickles, language, tags, feature, source)

def compile_feature(pickles, language, tags, feature, source)
  feature_background_steps = []
  feature.children.each do |child|
    if child.background
      feature_background_steps.concat(child.background.steps)
    elsif child.rule
      compile_rule(pickles, language, tags, feature_background_steps, child.rule, source)
    else
      scenario = child.scenario
      if scenario.examples.empty?
        compile_scenario(tags, feature_background_steps, scenario, language, pickles, source)
      else
        compile_scenario_outline(tags, feature_background_steps, scenario, language, pickles, source)
      end
    end
  end
end

def compile_rule(pickles, language, tags, feature_background_steps, rule, source)

def compile_rule(pickles, language, tags, feature_background_steps, rule, source)
  rule_background_steps = feature_background_steps.dup
  rule.children.each do |child|
    if child.background
      rule_background_steps.concat(child.background.steps)
    else
      scenario = child.scenario
      if scenario.examples.empty?
        compile_scenario(tags, rule_background_steps, scenario, language, pickles, source)
      else
        compile_scenario_outline(tags, rule_background_steps, scenario, language, pickles, source)
      end
    end
  end
end

def compile_scenario(feature_tags, background_steps, scenario, language, pickles, source)

def compile_scenario(feature_tags, background_steps, scenario, language, pickles, source)
  steps = scenario.steps.empty? ? [] : [].concat(pickle_steps(background_steps))
  tags = [].concat(feature_tags).concat(scenario.tags)
  scenario.steps.each do |step|
    steps.push(pickle_step(step))
  end
  pickle = Cucumber::Messages::Pickle.new(
    uri: source.uri,
    id: @id_generator.new_id,
    tags: pickle_tags(tags),
    name: scenario.name,
    language: language,
    ast_node_ids: [scenario.id],
    steps: steps
  )
  pickles.push(pickle)
end

def compile_scenario_outline(feature_tags, background_steps, scenario, language, pickles, source)

def compile_scenario_outline(feature_tags, background_steps, scenario, language, pickles, source)
  scenario.examples.reject { |examples| examples.table_header.nil? }.each do |examples|
    variable_cells = examples.table_header.cells
    examples.table_body.each do |values_row|
      value_cells = values_row.cells
      steps = scenario.steps.empty? ? [] : [].concat(pickle_steps(background_steps))
      tags = [].concat(feature_tags).concat(scenario.tags).concat(examples.tags)
      scenario.steps.each do |scenario_outline_step|
        step_props = pickle_step_props(scenario_outline_step, variable_cells, values_row)
        steps.push(Cucumber::Messages::Pickle::PickleStep.new(step_props))
      end
      pickle = Cucumber::Messages::Pickle.new(
        uri: source.uri,
        id: @id_generator.new_id,
        name: interpolate(scenario.name, variable_cells, value_cells),
        language: language,
        steps: steps,
        tags: pickle_tags(tags),
        ast_node_ids: [
          scenario.id,
          values_row.id
        ],
      )
      pickles.push(pickle)
    end
  end
end

def initialize(id_generator)

def initialize(id_generator)
  @id_generator = id_generator
end

def interpolate(name, variable_cells, value_cells)

def interpolate(name, variable_cells, value_cells)
  variable_cells.each_with_index do |variable_cell, n|
    value_cell = value_cells[n]
    name = name.gsub('<' + variable_cell.value + '>', value_cell.value)
  end
  name
end

def pickle_data_table(data_table, variable_cells, value_cells)

def pickle_data_table(data_table, variable_cells, value_cells)
  Cucumber::Messages::PickleStepArgument::PickleTable.new(
    rows: data_table.rows.map do |row|
      Cucumber::Messages::PickleStepArgument::PickleTable::PickleTableRow.new(
        cells: row.cells.map do |cell|
          Cucumber::Messages::PickleStepArgument::PickleTable::PickleTableRow::PickleTableCell.new(
            value: interpolate(cell.value, variable_cells, value_cells)
          )
        end
      )
    end
  )
end

def pickle_doc_string(doc_string, variable_cells, value_cells)

def pickle_doc_string(doc_string, variable_cells, value_cells)
  props = {
    content: interpolate(doc_string.content, variable_cells, value_cells)
  }
  if doc_string.content_type
    props[:content_type] = interpolate(doc_string.content_type, variable_cells, value_cells)
  end
  Cucumber::Messages::PickleStepArgument::PickleDocString.new(props)
end

def pickle_step(step)

def pickle_step(step)
  Cucumber::Messages::Pickle::PickleStep.new(pickle_step_props(step, [], nil))
end

def pickle_step_props(step, variable_cells, values_row)

def pickle_step_props(step, variable_cells, values_row)
  value_cells = values_row ? values_row.cells : []
  props = {
    id: @id_generator.new_id,
    ast_node_ids: [step.id],
    text: interpolate(step.text, variable_cells, value_cells),
  }
  if values_row
    props[:ast_node_ids].push(values_row.id)
  end
  if step.data_table
    data_table = Cucumber::Messages::PickleStepArgument.new(
      data_table: pickle_data_table(step.data_table, variable_cells, value_cells)
    )
    props[:argument] = data_table
  end
  if step.doc_string
    doc_string = Cucumber::Messages::PickleStepArgument.new(
      doc_string: pickle_doc_string(step.doc_string, variable_cells, value_cells)
    )
    props[:argument] = doc_string
  end
  props
end

def pickle_steps(steps)

def pickle_steps(steps)
  steps.map do |step|
    pickle_step(step)
  end
end

def pickle_tag(tag)

def pickle_tag(tag)
  Cucumber::Messages::Pickle::PickleTag.new(
    name: tag.name,
    ast_node_id: tag.id
  )
end

def pickle_tags(tags)

def pickle_tags(tags)
  tags.map {|tag| pickle_tag(tag)}
end