class Envirobly::Config

def append_image_tags!

def append_image_tags!
  @project.fetch(:services, {}).each do |logical_id, service|
    next if NON_BUILDABLE_TYPES.include?(service[:type]) || service[:image].present?
    checksums = []
    BUILD_DEFAULTS.each do |attribute, default|
      value = service.fetch(attribute, default)
      checksum = @commit.objects_with_checksum_at value
      if checksum.empty?
        @errors << "Service `#{logical_id}` specifies `#{attribute}` as `#{value}` which doesn't exist in this commit."
      else
        checksums << checksum
      end
    end
    if checksums.size == 2
      @project[:services][logical_id][:image_tag] = Digest::SHA1.hexdigest checksums.to_json
    end
  end
end

def compile(environment = nil)

def compile(environment = nil)
  @environment = environment
  return unless @project = parse
  set_project_url
  merge_environment_overrides! unless @environment.nil?
  transform_env_var_values!
  append_image_tags!
  @result = @project.slice(:services)
end

def dig(*args)

def dig(*args)
  @project.dig(*args)
rescue NoMethodError
  nil
end

def initialize(commit)

def initialize(commit)
  @commit = commit
  @errors = []
  @result = nil
  @project_url = nil
  @raw = @commit.file_content PATH
end

def merge_environment_overrides!

def merge_environment_overrides!
  return unless services = @project.dig(:environments, @environment.to_sym)
  services.each do |logical_id, service|
    service.each do |attribute, value|
      if value.is_a?(Hash) && @project[:services][logical_id][attribute].is_a?(Hash)
        @project[:services][logical_id][attribute].merge! value
        @project[:services][logical_id][attribute].compact!
      else
        @project[:services][logical_id][attribute] = value
      end
    end
  end
end

def parse

def parse
  YAML.safe_load @raw, aliases: true, symbolize_names: true
rescue Psych::Exception => exception
  @errors << exception.message
  nil
end

def set_project_url

def set_project_url
  @project_url = dig :remote, :origin
  if @project_url.blank?
    @errors << "Missing a `remote.origin` link to project."
  end
end

def to_deployment_params

def to_deployment_params
  {
    environ: {
      logical_id: @environment,
      project_url: @project_url
    },
    commit: {
      ref: @commit.ref,
      time: @commit.time,
      message: @commit.message
    },
    config: @result,
    raw_config: @raw
  }
end

def transform_env_var_values!

def transform_env_var_values!
  @project.fetch(:services, {}).each do |logical_id, service|
    service.fetch(:env, {}).each do |key, value|
      if value.is_a?(Hash) && value.has_key?(:file)
        @project[:services][logical_id][:env][key] = @commit.file_content(value.fetch(:file)).strip
      end
    end
  end
end