class KPM::BaseArtifact

def build_coordinates(group_id, artifact_id, packaging, classifier, version=nil)

def build_coordinates(group_id, artifact_id, packaging, classifier, version=nil)
  if classifier.nil?
    if version.nil?
      "#{group_id}:#{artifact_id}:#{packaging}"
    else
      "#{group_id}:#{artifact_id}:#{packaging}:#{version}"
    end
  else
    if version.nil?
      "#{group_id}:#{artifact_id}:#{packaging}:#{classifier}"
    else
      "#{group_id}:#{artifact_id}:#{packaging}:#{classifier}:#{version}"
    end
  end
end

def is_ruby_plugin_and_should_skip_top_dir(group_id, artifact_id)

def is_ruby_plugin_and_should_skip_top_dir(group_id, artifact_id)
  # The second check is for custom ruby plugins
  group_id == KILLBILL_RUBY_PLUGIN_GROUP_ID || artifact_id.include?('plugin')
end

def nexus_defaults

def nexus_defaults
  {
      url:        'https://repository.sonatype.org',
      repository: 'central-proxy'
  }
end

def nexus_remote(overrides={}, ssl_verify=true)

def nexus_remote(overrides={}, ssl_verify=true)
  nexus_remote ||= NexusCli::RemoteFactory.create(nexus_defaults.merge(overrides || {}), ssl_verify)
end

def path_looks_like_a_directory(path)

def path_looks_like_a_directory(path)
  # It already is!
  return true if File.directory?(path)
  # It already isn't!
  return false if File.file?(path)
  last_part = File.basename(path).downcase
  %w(.pom .xml .war .jar .xsd .tar.gz .tgz .gz .zip).each do |classic_file_extension|
    return false if last_part.end_with?(classic_file_extension)
  end
  # Known magic files
  %w(root).each do |classic_filename|
    return false if last_part == classic_filename
  end
  # Probably a directory
  true
end

def pull(logger, group_id, artifact_id, packaging='jar', classifier=nil, version='LATEST', destination_path=nil, overrides={}, ssl_verify=true)

def pull(logger, group_id, artifact_id, packaging='jar', classifier=nil, version='LATEST', destination_path=nil, overrides={}, ssl_verify=true)
  coordinates = build_coordinates(group_id, artifact_id, packaging, classifier, version)
  pull_and_put_in_place(logger, coordinates, destination_path, is_ruby_plugin_and_should_skip_top_dir(group_id, artifact_id), overrides, ssl_verify)
end

def pull_and_put_in_place(logger, coordinates, destination_path=nil, skip_top_dir=true, overrides={}, ssl_verify=true)

def pull_and_put_in_place(logger, coordinates, destination_path=nil, skip_top_dir=true, overrides={}, ssl_verify=true)
  destination_path = KPM::root if destination_path.nil?
  # Create the destination directory
  if path_looks_like_a_directory(destination_path)
    destination_dir = destination_path
  else
    destination_dir = File.dirname(destination_path)
  end
  FileUtils.mkdir_p(destination_dir)
  # Download the artifact in a temporary directory in case of failures
  info = {}
  Dir.mktmpdir do |tmp_destination_dir|
    logger.info "      Starting download of #{coordinates} to #{tmp_destination_dir}"
    info   = pull_and_verify(logger, coordinates, tmp_destination_dir, overrides, ssl_verify)
    # Move the file to the final destination, unpacking if necessary
    is_tgz = info[:file_path].end_with?('.tar.gz') || info[:file_path].end_with?('.tgz')
    if is_tgz
      Utils.unpack_tgz(info[:file_path], destination_path, skip_top_dir)
      FileUtils.rm info[:file_path]
    else
      FileUtils.mv info[:file_path], destination_path
    end
    # Update the info hash with the real destination
    if File.directory?(destination_path) && !is_tgz
      destination = File.join(File.expand_path(destination_path), info[:file_name])
    else
      destination = destination_path
    end
    info[:file_path] = File.expand_path(destination)
    if is_tgz
      info[:file_name] = nil
      info[:size]      = nil
    else
      info[:file_name] = File.basename(destination)
    end
    logger.info "Successful installation of #{coordinates} to #{info[:file_path]}"
  end
  info
end

def pull_and_verify(logger, coordinates, destination_dir, overrides={}, ssl_verify=true)

def pull_and_verify(logger, coordinates, destination_dir, overrides={}, ssl_verify=true)
  info = nexus_remote(overrides, ssl_verify).pull_artifact(coordinates, destination_dir)
  raise ArtifactCorruptedException unless verify(logger, coordinates, info[:file_path], overrides, ssl_verify)
  info
end

def verify(logger, coordinates, file_path, overrides={}, ssl_verify=true)

def verify(logger, coordinates, file_path, overrides={}, ssl_verify=true)
  artifact_info = nexus_remote(overrides, ssl_verify).get_artifact_info(coordinates)
  sha1_element  = REXML::Document.new(artifact_info).elements['//sha1']
  # Can't check :(
  if sha1_element.nil?
    logger.warn("Unable to find sha1 in Nexus repo for #{coordinates}. Artifact info: #{artifact_info.inspect}")
    return true
  end
  local_sha1 = Digest::SHA1.file(file_path).hexdigest
  sha1       = sha1_element.text
  local_sha1 == sha1
end