import os
import subprocess
import sys
import threading
import time
import traceback

import git
import requests
from decouple import Config, RepositoryEnv

DOTENV_FILE = 'futplus/.env'
env_config = Config(RepositoryEnv(DOTENV_FILE))


def process_exists(process_name):
    call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name, '/FI', "USERNAME eq %username%"
    output = subprocess.check_output(call, shell=True).decode()
    last_line = output.strip().split('\r\n')[-1]
    return last_line.lower().startswith(process_name.lower())


if getattr(sys, 'frozen', False):
    BASE_DIR = os.path.dirname(sys.executable)
else:
    BASE_DIR = os.path.dirname(os.path.realpath(__file__))


def run_console_sbc_manager():
    base_dir_file = open(os.path.join(BASE_DIR, 'path.txt'), 'r')
    base_dir = base_dir_file.read()
    order = '"C:\Windows\explorer.exe" ' + os.path.join(base_dir, 'run_program.cmd')
    print(order)
    os.system(order)
    # subprocess.run(order, shell=False)


# run_console_squad_manager is copy of run_console_sbc_manager
def run_console_squad_manager():
    base_dir_file = open(os.path.join(BASE_DIR, 'path.txt'), 'r')
    base_dir = base_dir_file.read()
    order = '"C:\Windows\explorer.exe" ' + os.path.join(base_dir, 'run_program.cmd')
    print(order)
    os.system(order)


with open(os.path.join(BASE_DIR, 'status_update_time.txt'), 'w') as status_time_file:
    status_time_file.write(str(time.time()))

try:
    open(os.path.join(BASE_DIR, 'path.txt'), 'r')
    raise Exception('make it every time')
except:
    print('need to create path.txt')
    temp_base_dir = open(os.path.join(BASE_DIR, 'path.txt'), 'w')
    temp_base_dir.write(str(BASE_DIR))
    temp_base_dir.close()
try:
    open(os.path.join(BASE_DIR, 'run_program.cmd'), 'r')
    raise Exception('make it every time')
except:
    print('need to create run_program.cmd')
    temp_cmd = open(os.path.join(BASE_DIR, 'run_program.cmd'), 'w')
    text = '''cd %s
start "%s" run_console_manager.exe''' % (BASE_DIR, BASE_DIR)
    temp_cmd.write(str(text))
    temp_cmd.close()

try:
    open(os.path.join(BASE_DIR, 'run_gamepad.cmd'), 'r')
    raise Exception('make it every time')
except:
    print('need to create run_gamepad.cmd')
    temp_cmd = open(os.path.join(BASE_DIR, 'run_gamepad.cmd'), 'w')
    text = '''cd %s
start "%s" run_gamepad_manager.exe''' % (BASE_DIR, BASE_DIR)
    temp_cmd.write(str(text))
    temp_cmd.close()

# put_on_rest_mode()
has_error = False


def kill_gamepad_program():
    try:
        os.system('TASKKILL /F /IM uniq_xbox_gamepad.exe /FI "USERNAME eq %username%"')
        time.sleep(1)
    except:
        print('no active gamepad program found ...')


def kill_python_program():
    print('kill python program')
    try:
        os.system('TASKKILL /F /IM python.exe /FI "USERNAME eq %username%"')
        time.sleep(1)
        # os.system('TASKKILL /F /IM run_gamepad_manager.exe')
        os.system('TASKKILL /F /IM run_console_manager.exe /FI "USERNAME eq %username%"')
        os.system('TASKKILL /F /IM run_console_manager.exe /FI "USERNAME eq %username%"')
        os.system('TASKKILL /F /IM run_console_manager.exe /FI "USERNAME eq %username%"')
        os.system('TASKKILL /F /IM console_squad_manager.exe /FI "USERNAME eq %username%"')
        os.system('TASKKILL /F /IM console_squad_manager.exe /FI "USERNAME eq %username%"')
        os.system('TASKKILL /F /IM console_squad_manager.exe /FI "USERNAME eq %username%"')
    except:
        print('no active python program found ...')


# def put_on_rest_mode_by_mother():
#     from sbc.sbc_solver import SBCSolver
#     global fifa_account
#     print('need to put on rest mode')
#     console = Console.objects.filter(name=CONSOLE_NAME).first()
#     fifa_accounts = FifaAccount.objects.filter(console=console).all()
#     if fifa_accounts.first() and fifa_accounts.first().platform in ['xboxs', 'xbox360']:
#         print('no need to put on rest mode on xbox')
#         return
#     must_break = False
#     for fifa_account in fifa_accounts:
#         existed_sbc_worker = SBCWorker.objects.filter(
#             is_done=False, has_error=False, running_platform='console', fifa_account=fifa_account).first()
#         if existed_sbc_worker:
#             print('found existed sbc worker')
#             sbc_solver_item = SBCSolver(existed_sbc_worker.id, existed_sbc_worker.fifa_account.id,
#                                         existed_sbc_worker.fifa_account.user_name,
#                                         existed_sbc_worker.fifa_account.password,
#                                         existed_sbc_worker.fifa_account.platform, existed_sbc_worker.manual_loyal)
#             sbc_solver_item.public_moves.console_open_ultimate(state_set='play_main')
#             # sbc_solver_item.console_close_ultimate(need_get_new_sid=False)
#             # if need_to_put_on_rest_mode:
#             sbc_solver_item.public_moves.put_on_rest_mode()
#             sbc_solver_item.public_moves.ps4_buttons.__del__()
#             del sbc_solver_item
#             time.sleep(2)
#             break


def uniq_xbox_gamepad_starter():
    starter_text = '''
    start %s\\uniq_xbox_gamepad.exe''' % BASE_DIR
    os.system(starter_text)
    # base_dir_file = open(os.path.join(BASE_DIR, 'path.txt'), 'r')
    # base_dir = base_dir_file.read()
    # order = '"C:\Windows\explorer.exe" ' + os.path.join(base_dir, 'run_gamepad.cmd')
    # print(order)
    # os.system(order)


if __name__ == '__main__':
    while True:
        try:
            # get_screen_shot()
            # console = Console.objects.filter(name=CONSOLE_NAME).first()
            # if not console:
            #     print('no console found wait 120 secs')
            #     time.sleep(120)
            #     continue
            #
            # existed_sbc_worker = ''
            # fifa_accounts = FifaAccount.objects.filter(console=console).all()
            # for fifa_account in fifa_accounts:
            #     existed_sbc_worker = SBCWorker.objects.filter(is_done=False, has_error=False,
            #                                                           running_platform='console', fifa_account=fifa_account,
            #                                                           manual_loyal=True).first()
            #     if existed_sbc_worker:
            #         break
            #
            # if existed_sbc_worker:
            #     print('existed_sbc_worker.fifa_account.can_kill_by_mother = ',existed_sbc_worker.fifa_account.can_kill_by_mother)
            #     try:
            #         if has_image('screen_shot_cropped_tmp.png', 'screen_shot_tmp.jpg') and existed_sbc_worker.fifa_account.can_kill_by_mother:
            #             print('screen shots are the same in 120 secs. will kill python program')
            #             has_error = True
            #     except:
            #         print(traceback.format_exc())
            try:
                main_site_address = env_config('MAIN_SITE_ADDRESS', default='http://142.132.177.244:8000')
                program_version = requests.get(f'{main_site_address}/accounts/get-last-version/', timeout=20).json()
            except:
                print('can`t get version : ', traceback.format_exc())
                time.sleep(120)
                continue

            if has_error:
                has_error = False
                kill_python_program()
                time.sleep(2)

                # put_on_rest_mode_by_mother()
            try:
                closed_old = False
                with open(os.path.join(BASE_DIR, 'status_update_time.txt'), 'r') as status_time_file:
                    status_time_text = status_time_file.read()
                    if float(status_time_text) < time.time() - (50*60):
                        print('more than 50 minutes not updated . close console squad manager')
                        kill_python_program()
                        time.sleep(10)
                        closed_old = True
                if closed_old:
                    with open(os.path.join(BASE_DIR, 'status_update_time.txt'), 'w') as status_time_file:
                        status_time_file.write(str(time.time()))
            except:
                print('cant read status_update_time.txt')
            try:
                current_version = open('version.txt', 'r')
            except:
                default_version = open('version.txt', 'w')
                default_version.write('0')
                default_version.close()
                current_version = open('version.txt', 'r')
            current_version = current_version.read()
            if str(program_version.get('number')) != str(current_version):
                # if False:
                print('need to update program')
                if (program_version.get('need_to_close_python_program') or
                        program_version.get('need_to_put_on_rest_mode')):
                    print('need to kill python program')
                    kill_python_program()
                    time.sleep(2)

                    # put_on_rest_mode_by_mother()
                if program_version.get('need_to_reset_gamepad'):
                    print('need to kill xbox gamepad')
                    threading.Thread(target=kill_gamepad_program).start()

                print('pulling from git ...')
                base_dir_file = open(os.path.join(BASE_DIR, 'path.txt'), 'r')
                base_dir = base_dir_file.read()
                g = git.cmd.Git(base_dir)
                res = g.pull()
                time.sleep(2)
                print('installing requirements ...')
                os.system('python -m pip install -r %s/requirements.txt' % base_dir)
                os.system('python -m pip install -r %s/windows_requirements.txt' % base_dir)

                print('updating the version ...')
                new_version = open('version.txt', 'w')
                new_version.write(str(program_version.get('number')))
                new_version.close()
                print('version is updated now')
            if not process_exists('run_console_manager.exe'):
                if program_version.get('need_to_open_python_program'):
                    print('need to open console squad manager')
                    # threading.Thread(target=run_console_sbc_manager).start()
                    threading.Thread(target=run_console_squad_manager).start()
            # running_platform = Console.objects.get(name=CONSOLE_NAME).fifaaccount_set.first().platform
            # if running_platform in ['xboxs', 'xbox360'] and not process_exists('uniq_xbox_gamepad.exe'):
            if not process_exists('uniq_xbox_gamepad.exe'):
                print('need to open uniq_xbox_gamepad')
                threading.Thread(target=uniq_xbox_gamepad_starter).start()

            # time.sleep(120)
        except:
            print(traceback.format_exc())
            has_error = True
            # close_old_connections()

        # get_screen_shot()
        # get_picture_cropped()
        time.sleep(120)

    # add path.txt , run_program.cmd
    # add python -m pip install requirements.txt

# todo : for convert this file to .exe enter bellow in terminal
# ViGEmClient.dll is for windows 64 bit
# python -m PyInstaller --onefile --icon=utils\\greate_manager.ico .\console_greate_manager.py
