import os
import re
import signal
import subprocess
import sys
import time
import traceback
import psutil
from format_convert import timeout_decorator

from format_convert import get_memory_info
from format_convert.judge_platform import get_platform
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')


def monitor_libreoffice():
    try:
        # logging.info("=========================================")
        logging.info("into monitor_libreoffice")
        # logging.info("------------------------------MEM top 10")
        os.system("ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head")
        #
        # logging.info("--------------------------soffice process")
        # os.system("ps -ef | grep soffice")

        pids = psutil.pids()
        for pid in pids:
            try:
                process = psutil.Process(pid)
                # if process.username() == "appuser":
                if re.search("soffice|unrar", process.exe()):
                    # if time.time() - process.create_time() >= 120:

                    # logging.info("---------------------------killed soffice")
                    # print("process", pid, process.exe())
                    logging.info("process " + str(pid) + str(process.exe()))
                    comm = "kill -9 " + str(pid)
                    # subprocess.call(comm, shell=True)
                    os.system(comm)
                    # print("killed", pid)
                    logging.info("killed " + str(pid))

            except TimeoutError:
                raise TimeoutError
            except:
                continue
        # logging.info("=========================================")
    except TimeoutError:
        raise TimeoutError


# @timeout_decorator.timeout(120, timeout_exception=TimeoutError, use_signals=False)
def office_convert(src_path, dest_path, target_format, retry_times=1):
    try:
        logging.info("into office_convert")
        print("src_path", src_path)
        uid1 = src_path.split(os.sep)[-1].split(".")[0]
        dest_file_path = dest_path + uid1 + "." + target_format
        src_format = src_path.split(".")[-1]

        # 重试转换
        for i in range(retry_times):
            # 调用Win下的libreoffice子进程
            if get_platform() == "Windows":
                soffice = 'C:\\Program Files\\LibreOfficeDev 5\\program\\soffice.exe'
                comm_list = [soffice, '--headless', '--convert-to', target_format, src_path,
                             '--outdir', dest_path+os.sep]

                try:
                    p = subprocess.call(comm_list, timeout=30*(i+2))

                except:
                    continue

            # 调用Linux下的libreoffice子进程
            else:
                # 先杀libreoffice进程
                monitor_libreoffice()

                # 再调用转换
                libreoffice_dir = 'soffice'
                comm_list = [libreoffice_dir, '--headless', '--convert-to', target_format, src_path,
                             '--outdir', dest_path+os.sep]

                comm = ''
                for c in comm_list:
                    comm += c + ' '
                # logging.info("office_convert command" + comm)
                try:
                    # p = subprocess.call(comm_list, timeout=30*(i+2))
                    os.system(comm)
                except TimeoutError:
                    return [-5]
                except Exception as e:
                    print(src_format + ' to ' + target_format + ' Failed! Retry...', i, 'times')
                    print(traceback.print_exc())
                    continue

            # 执行失败，重试
            if not os.path.exists(dest_file_path):
                print(src_format + ' to ' + target_format + ' Failed! Retry...', i, 'times')
                continue
            # 执行成功，跳出循环
            else:
                break

        # 重试后还未成功
        if not os.path.exists(dest_file_path):
            # print(src_format + ' to ' + target_format + ' failed!')
            logging.info(src_format + ' to ' + target_format + " failed!")
            return [-3]

        logging.info("out office_convert")
        return dest_file_path
    except TimeoutError:
        return [-5]
