#!/usr/bin/env python

import rpm
import sys
import datetime
import os
import socket
import subprocess
import shutil
import json


package_info = {'arch': [], 'epoch': [], 'name': [], 'release': [], 'vendor': [], 'version': []}
rpm_tags = ['arch', 'epoch', 'name', 'release', 'vendor', 'version']

utc_time = datetime.datetime.now().strftime("%Y-%m-%d-%s/")
log_dir = '/var/spool/abrt-criu/criu-{}/'.format(utc_time)
vz_dump_logs = '/vz/dump/'
failed_container_ids = []

def get_rpm_info(pkg):
    ts = rpm.TransactionSet()
    mi = ts.dbMatch( 'name', pkg )
    try :
        h = mi.next()
        # rpm --queryformat "%{ARCH} %{EPOCH} %{NAME} %{RELEASE} %{VENDOR} %{VERSION}" -q criu
        for item in rpm_tags:
            if h[item] is None:
               package_info[item].append(str(0))
            else:
               package_info[item].append(h[item])
    except StopIteration:
        print "Package not found"
        return 'not_found'


def get_ct_proc(container_id):
    ct_proc = {}
    try:
       print('checking ct id: {}'.format(container_id))
       it_exist = subprocess.check_call(['/usr/bin/prlctl', 'status', container_id])
    except subprocess.CalledProcessError:
       # if not 0 here, it's mean that container not exist
       print('ct id: {} removed'.format(container_id))
       pass
    except OSError:
       pass
    else:
       try:
          procps = subprocess.check_output(['/usr/bin/vzps', 'faxh', '-octid,cmd', '-E', container_id]).decode()
          for process in procps.splitlines():
              if container_id not in ct_proc:
                 ct_proc[container_id] = [process.strip().strip(container_id)]
              else:
                 ct_proc[container_id].append(process.strip().strip(container_id))
       # such exception needed if binaries not exist
       except subprocess.CalledProcessError:
          return ct_proc
       except OSError:
          # empty
          return ct_proc
    return ct_proc


def copy_logs():
    phaul_log = '/var/log/phaul.log'
    shutil.copy('/etc/os-release', os.path.join(log_dir, 'os_info'))
    if os.path.exists(phaul_log):
       shutil.copy(phaul_log, os.path.join(log_dir, 'phaul.log'))
    if os.path.exists(vz_dump_logs):
       for item in next(os.walk(vz_dump_logs))[1]:
           # collect containers with issues
           # on a dump stage
           if item not in failed_container_ids:
               failed_container_ids.append(item)
               if not os.path.exists(os.path.join(log_dir, item)):
                   shutil.copytree(os.path.join(vz_dump_logs, item), os.path.join(log_dir, item))


def main():
    if not os.path.exists(log_dir):
       os.makedirs(log_dir)
    copy_logs()
    get_rpm_info('criu')
    pkg_components = ['pkg_arch', 'pkg_epoch', 'pkg_name', 'pkg_release', 'pkg_vendor', 'pkg_version']

    for item in rpm_tags:
        with open(os.path.join(log_dir, '/pkg_' + item), 'a') as the_component:
             the_component.write(' '.join(package_info[item]))

    with open(os.path.join(log_dir, 'component'), 'a') as the_component:
         the_component.write(' '.join(package_info['name']))

    with open(os.path.join(log_dir, 'kernel'), 'a') as the_component:
         the_component.write(os.uname()[2])

    with open(os.path.join(log_dir, 'hostname'), 'a') as the_component:
         the_component.write(socket.gethostname())

    with open(os.path.join(log_dir, 'runlevel'), 'a') as the_component:
         the_component.write(subprocess.check_output(['runlevel']).decode())

    with open(os.path.join(log_dir, 'reason'), 'a') as the_reason:
         the_reason.write('criu migration failed')

    with open(os.path.join(log_dir, 'package'), 'a') as the_package:
         the_package.write(('{}-{}-{}').format(''.join(package_info['name']), ''.join(package_info['version']), ''.join(package_info['release'])))

    for failed_ct in failed_container_ids:
        with open(os.path.join(log_dir, failed_ct + '/running_processes.json'), 'a') as the_failed_ct:
             the_failed_ct.write(json.dumps(get_ct_proc(failed_ct)))

    os.environ['DUMP_DIR'] = log_dir
    os.system("reporter-vz-prlrep")



if __name__ == '__main__':
     main()
