#!/usr/bin/env ruby
# SPDX-License-Identifier: MulanPSL-2.0+
# Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved.
# frozen_string_literal: true

require 'fileutils'
require 'optparse'
require 'json'
require 'securerandom'

require_relative 'lib/common'
require_relative '../lib/mq_client'

opt = {}
options = OptionParser.new do |opts|
  opts.banner = 'Usage: multi-qemu -n -c -q -l -i -h'

  opts.separator ''
  opts.on('-n HOSTNAME_PREFIX', '--name HOSTNAME_PREFIX', 'format: $tbox_group.$HOSTNAME') do |name|
    opt['hostname_prefix'] = name
  end

  opts.on('-c count', '--count count', 'how many VM do you need') do |num|
    opt['nr_vm'] = num
  end

  opts.on('-q queues', '--queues queues', 'separated by ","') do |queues|
    opt['queues'] = queues
  end

  opts.on('-l log_dir', '--log_dir log_dir', 'directory for save qemu log') do |dir|
    opt['log_dir'] = dir
  end

  opts.on('-i index', '--index index', 'index of multi-qemu, used for safe-stop') do |index|
    opt['index'] = index
  end

  opts.on_tail('-h', '--help', 'show this message') do
    puts opts
    exit
  end
end

if ARGV.size.zero?
  puts options
  exit 1
end

options.parse!(ARGV)

# Run multiple QEMU in parallel
PWD      = Dir.pwd
HOSTNAME = opt['hostname_prefix'] || "vm-2p8g.#{ENV['HOSTNAME']}"
NR_VM    = opt['nr_vm'] || 1
QUEUES   = opt['queues'] || "#{ENV['HOSTNAME']}.#{RUBY_PLATFORM.split('-')[0]}"
LOG_DIR  = opt['log_dir'] || '/srv/cci/serial/logs'
INDEX    = opt['index']

UUID = SecureRandom.uuid
SUITE_FILE = "/tmp/#{ENV['HOSTNAME']}/suite"
SAFE_STOP_FILE = "/tmp/#{ENV['HOSTNAME']}/safe-stop"
RESTART_FILE = "/tmp/#{ENV['HOSTNAME']}/restart/#{UUID}"
RESTART_LOCK_FILE = "/tmp/#{ENV['HOSTNAME']}/restart/lock"

SCHED_HOST = ENV['LKP_SERVER'] || '172.17.0.1'
SCHED_PORT = ENV['LKP_CGI_PORT'] || '3000'
MQ_HOST = ENV['MQ_HOST'] || ENV['LKP_SERVER'] || '172.17.0.1'
MQ_PORT = ENV['MQ_PORT'] || 5672

def main(hostname)
  start_qemu(hostname)
end

def start_qemu(hostname)
  pwd_hostname = File.join(PWD, hostname)
  FileUtils.mkdir_p(pwd_hostname) unless File.exist?(pwd_hostname)
  system(
    { 'hostname' => hostname,
      'queues' => "#{QUEUES},#{hostname}",
      'log_dir' => LOG_DIR,
      'UUID' => UUID,
      'index' => INDEX,
      'WORKSPACE' => pwd_hostname },
    ENV['CCI_SRC'] + '/providers/qemu.sh'
  )
end

def loop_main(hostname, thr)
  loop do
    begin
      thr.exit if File.exist?(SAFE_STOP_FILE)
      main(hostname)
    rescue StandardError => e
      puts e.backtrace
      # if an exception occurs, request the next time after 30 seconds
      sleep 25
    ensure
      sleep 5
    end
  end
end

def multiqemu
  reboot_thr = Thread.new do
    loop_reboot_testbox(HOSTNAME, 'vm', MQ_HOST, MQ_PORT)
  end

  threads = {}
  NR_VM.to_i.times do |i|
    thr = Thread.new do
      loop_main("#{HOSTNAME}-#{i}", thr)
    end
    threads[i] = thr
  end

  manage_thr = Thread.new do
    manage_multi_qemu_docker(threads.merge({ 'manage' => manage_thr }), MQ_HOST, MQ_PORT)
  end

  threads.each do |_, thr|
    thr.join
  end

  manage_thr.exit
  reboot_thr.exit
  puts 'all threads exit'

  safe_stop
  puts "#{UUID} exit"
end

if $PROGRAM_NAME == __FILE__
  save_running_suite
  multiqemu
end
