class Krane::Renderer

def bind_template_variables(erb_binding, variables)

def bind_template_variables(erb_binding, variables)
  variables.each do |var_name, value|
    erb_binding.local_variable_set(var_name, value)
  end
end

def find_partial(name)

def find_partial(name)
  partial_names = [name + '.yaml.erb', name + '.yml.erb']
  @partials_dirs.each do |dir|
    partial_names.each do |partial_name|
      partial_path = File.join(dir, partial_name)
      return partial_path if File.exist?(partial_path)
    end
  end
  raise PartialNotFound.new("Could not find partial '#{name}' in any of #{@partials_dirs.join(':')}",
    filename: name)
end

def initialize(current_sha:, template_dir:, logger:, bindings: {}, partials_dir: nil)

def initialize(current_sha:, template_dir:, logger:, bindings: {}, partials_dir: nil)
  @current_sha = current_sha
  @template_dir = template_dir
  @partials_dirs =
    %w(partials ../partials).map { |d| File.expand_path(File.join(@template_dir, d)) }
  # Prepend the partial_dir to the list of partials_dirs so that the user-provided
  # directory is used first.
  @partials_dirs.unshift(File.expand_path(partials_dir)) if partials_dir
  @logger = logger
  @bindings = bindings
  # Max length of podname is only 63chars so try to save some room by truncating sha to 8 chars
  @id = if ENV["TASK_ID"]
    ENV["TASK_ID"]
  elsif current_sha
    current_sha[0...8] + "-#{SecureRandom.hex(4)}"
  else
    SecureRandom.hex(8)
  end
end

def render_partial(partial, locals)

def render_partial(partial, locals)
  variables = template_variables.merge(locals)
  erb_binding = TemplateContext.new(self).template_binding
  bind_template_variables(erb_binding, variables)
  erb_binding.local_variable_set("locals", locals)
  partial_path = find_partial(partial)
  template = File.read(partial_path)
  expanded_template = ERB.new(template, trim_mode: '-').result(erb_binding)
  docs = Psych.parse_stream(expanded_template, filename: partial_path)
  # If the partial contains multiple documents or has an explicit document header,
  # we know it cannot validly be indented in the parent, so return it immediately.
  return expanded_template unless docs.children.one? && docs.children.first.implicit
  # Make sure indentation isn't a problem by producing a single line of parseable YAML.
  # Note that JSON is a subset of YAML.
  JSON.generate(docs.children.first.to_ruby)
rescue PartialNotFound => err
  # get the filename from the first parent, not the missing partial itself
  raise err if err.filename == partial
  raise InvalidPartialError.new(err.message, filename: partial, content: expanded_template || template)
rescue InvalidPartialError => err
  err.parents = err.parents.dup.unshift(File.basename(partial_path))
  raise err
rescue StandardError => err
  raise InvalidPartialError.new(err.message, filename: partial_path, content: expanded_template || template)
end

def render_template(filename, raw_template)

def render_template(filename, raw_template)
  return raw_template unless File.extname(filename) == ".erb"
  erb_binding = TemplateContext.new(self).template_binding
  bind_template_variables(erb_binding, template_variables)
  ERB.new(raw_template, trim_mode: '-').result(erb_binding)
rescue InvalidPartialError => err
  err.parents = err.parents.dup.unshift(filename)
  err.filename = "#{err.filename} (partial included from: #{err.parents.join(' -> ')})"
  raise err
rescue StandardError => err
  raise InvalidTemplateError.new(err.message, filename: filename, content: raw_template)
end

def template_variables

def template_variables
  {
    'current_sha' => @current_sha,
    'deployment_id' => @id,
  }.merge(@bindings)
end