#!/usr/bin/env ruby

require 'yaml'

class DefaultVersionIdentifier
  attr_accessor :requested_dependency_name
  attr_accessor :default_dependency_versions
  attr_accessor :dependencies

  def initialize(manifest_path, requested_dependency_name)
    raise bad_arguments_error_message if manifest_path.nil? || requested_dependency_name.nil?

    @requested_dependency_name = requested_dependency_name
    manifest = YAML.load_file(manifest_path)
    @default_dependency_versions = manifest['default_versions'] || raise(defaults_misconfigured_error_message)
    @dependencies = manifest['dependencies']
  end

  def bad_arguments_error_message
    'Must provide both a buildpack manifest and dependency'
  end

  def defaults_misconfigured_error_message
    "The buildpack manifest is misconfigured for 'default_versions'. " +
    'Contact your Cloud Foundry operator/admin. For more information, see ' +
    'https://docs.cloudfoundry.org/buildpacks/custom.html#specifying-default-versions'
  end

  def run
    dependency_defaults = default_dependency_versions.select { |default_dependency_versions_entry| default_dependency_versions_entry['name'] == requested_dependency_name }
		if dependency_defaults.empty?
			dependency_defaults = @dependencies.select { |d| d['name'] == requested_dependency_name && (d['cf_stacks'].nil? || d['cf_stacks'].include?(ENV['CF_STACK'])) }
		end
		verify_single_default_dependency_version_provided(dependency_defaults)

    default_dependency_version = dependency_defaults.first['version']
    verify_availability_of_requested_dependency(requested_dependency_name, default_dependency_version, dependencies)

    STDERR.puts "DEBUG: default_version_for #{requested_dependency_name} is #{default_dependency_version}" if ENV['BP_DEBUG']
    print default_dependency_version
  end

  def verify_single_default_dependency_version_provided(dependency_defaults)
    default_descriptions_found = dependency_defaults.size
    if default_descriptions_found != 1
      raise defaults_misconfigured_error_message
    end
  end

  def verify_availability_of_requested_dependency(requested_dependency_name, default_dependency_version, dependencies)
    matched_dependencies = dependencies.select { |dependency| dependency['name'] == requested_dependency_name && dependency['version'] == default_dependency_version }
    if matched_dependencies.empty?
      raise defaults_misconfigured_error_message
    end
  end
end

DefaultVersionIdentifier.new(ARGV[0], ARGV[1]).run
