class Gitlab::QA::Component::Gitlab

def add_network_alias(name)

def add_network_alias(name)
  @network_aliases.push(name)
end

def address

def address
  "http://#{hostname}"
end

def ensure_configured!

def ensure_configured!
  raise 'Please configure an instance first!' unless [name, release, network].all?
end

def hostname

def hostname
  "#{name}.#{network}"
end

def initialize

def initialize
  @docker = Docker::Engine.new
  @environment = {}
  @volumes = {}
  @network_aliases = []
  self.release = 'CE'
end

def instance

def instance
  raise 'Please provide a block!' unless block_given?
  prepare
  start
  reconfigure
  wait
  yield self
  teardown
end

def name

def name
  @name ||= "gitlab-#{edition}-#{SecureRandom.hex(4)}"
end

def omnibus_config=(config)

def omnibus_config=(config)
  @environment['GITLAB_OMNIBUS_CONFIG'] = config.tr("\n", ' ')
end

def prepare

def prepare
  @docker.pull(image, tag)
  return if @docker.network_exists?(network)
  @docker.network_create(network)
end

def pull

def pull
  @docker.pull(@release.image, @release.tag)
end

def reconfigure

def reconfigure
  @docker.attach(name) do |line, wait|
    puts line
    # TODO, workaround which allows to detach from the container
    #
    Process.kill('INT', wait.pid) if line =~ /gitlab Reconfigured!/
  end
end

def release=(release)

def release=(release)
  @release = Release.new(release)
end

def restart

def restart
  @docker.restart(name)
end

def sha_version

def sha_version
  json = @docker.read_file(
    @release.image, @release.tag,
    '/opt/gitlab/version-manifest.json'
  )
  manifest = JSON.parse(json)
  manifest['software']['gitlab-rails']['locked_version']
end

def start # rubocop:disable Metrics/AbcSize

rubocop:disable Metrics/AbcSize
def start # rubocop:disable Metrics/AbcSize
  ensure_configured!
  docker.run(image, tag) do |command|
    command << '-d -p 80'
    command << "--name #{name}"
    command << "--net #{network}"
    command << "--hostname #{hostname}"
    @volumes.to_h.each do |to, from|
      command.volume(to, from, 'Z')
    end
    command.volume(File.join(Runtime::Env.host_artifacts_dir, name, 'logs'), '/var/log/gitlab', 'Z')
    @environment.to_h.each do |key, value|
      command.env(key, value)
    end
    @network_aliases.to_a.each do |network_alias|
      command << "--network-alias #{network_alias}"
    end
  end
end

def teardown

def teardown
  raise 'Invalid instance name!' unless name
  @docker.stop(name)
  @docker.remove(name)
end

def wait

def wait
  if Availability.new(name).check(180)
    sleep 12 # TODO, handle that better
    puts ' -> GitLab is available.'
  else
    abort ' -> GitLab unavailable!'
  end
end