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

# rootfs test via job, including cifs, initramfs files
# boot way kvm.
# input: job yaml, os, os_version, os_arch, os_mount, testbox.
# output: a test report, including log print time, job ID, os, runtime, job state and url to check logs, and send mail.
# Eg: test report format:
# [2020-11-26 19:22:22 +0800]: ["crystal.143338", "centos", "aarch64", "7.6.1810", "cifs", 2020-11-26 19:21:12 +0800,
# 2020-11-26 19:22:21 +0800, 69, "finished", "/result/iperf-walk-os-test/vm-2p8g/2020-11-26/crystal.143338"]

require "#{ENV['CCI_SRC']}/lib/es_query"
require "#{ENV['LKP_SRC']}/lib/monitor"
require "#{ENV['CCI_SRC']}/lib/mail_client"

require 'time'
require 'logger'
require 'rufus-scheduler'

TEST_OS = ['openeuler aarch64 20.03',
           'centos aarch64 7.6.1810',
           'centos aarch64 7.8.2003',
           'centos aarch64 8.1.1911',
           'debian aarch64 sid',
           'archlinux aarch64 2020-11-12'].freeze

TEST_YAML = 'iperf-walk-os.yaml'

TESTBOX = 'vm-2p8g'

LOG = 'walk-test.report'

OS_MOUNT = %w[cifs initramfs].freeze

EMAIL_ADDRESS = (ENV['USER']).to_s.freeze

def mail_report
  message = File.read(LOG).chomp
  data = "
  subject: os rootfs test report
  to: #{EMAIL_ADDRESS}
  body: #{message}"

  email = MailClient.new
  email.send_mail(data)
end

def write_report(report_all)
  File.open(LOG, 'a') do |f|
    log = Logger.new(f, 'weekly')
    log.formatter = proc { |_severity, datetime, _progname, msg|
      "[#{datetime}]: #{msg}\n"
    }
    log.info(report_all)
  end
end

def monitor(query, actions, timeout)
  monitor = Monitor.new
  monitor.overrides = query
  monitor.action = actions
  monitor.run(timeout)
  monitor
end

def monitor_state(job_id)
  time_list = []

  %w[boot extract_finished].each do |state|
    result_array = monitor({ 'job_id' => job_id, 'job_state' => state }, { 'stop' => true }, '1800').result
    time_list.push(Time.parse(result_array[0]['time'])) unless result_array.empty?
  end
  time_list
end

def es_search(job_id)
  es_list = []

  es = ESQuery.new
  result_dict = es.query_by_id(job_id)
  %w[job_state result_root].each do |field|
    es_list.push(result_dict[field]) unless result_dict.nil?
  end
  es_list
end

def find_by_id(job_id)
  start_time, end_time = monitor_state(job_id)
  cost_time = end_time - start_time unless end_time.nil?

  job_state, result_root = es_search(job_id)

  return start_time, end_time, cost_time.to_i.floor, job_state, result_root
end

def run_qemu
  Process.fork do
    %x(#{ENV['CCI_SRC']}/providers/my-qemu.sh >/dev/null 2>&1)
  end
end

def submit_job(os_args, os_mount)
  `submit #{TEST_YAML} --my-queue 'os|os_arch|os_version=#{os_args}' testbox=#{TESTBOX} os_mount=#{os_mount}`
end

def traversal_os_mount
  OS_MOUNT.each do |os_mount|
    traversal_test_os(os_mount)
  end
end

def traversal_test_os(os_mount)
  TEST_OS.each do |os_str|
    os_args = os_str.gsub(' ', '|')
    test_rootfs(os_args, os_mount)
  end
end

def test_rootfs(os_args, os_mount)
  message = submit_job(os_args, os_mount).chomp
  job_id = message.split('=')[1]
  run_qemu

  job_result = if message.include? 'error'
                 []
               else
                 find_by_id(job_id)
               end

  report_all = job_id.split(', ') + os_args.split + os_mount.split + job_result
  write_report(report_all)
end

def cron_job
  test = Rufus::Scheduler.new
  test.cron '0 8-22 * * *' do
    traversal_os_mount
  end

  mail = Rufus::Scheduler.new
  mail.cron '0 8 * * 1' do
    mail_report
  end

  [test, mail].each(&:join)
end

cron_job
