# %%
PROJECT_PATH = '/home/md/Work/ligalytics/leagues_stable/'
import os, sys
sys.path.insert(0, PROJECT_PATH)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "leagues.settings")
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"

from leagues import settings
# settings.DATABASES['default']['NAME'] = PROJECT_PATH+'/db.sqlite3'
settings.DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
settings.DATABASES['default']['HOST'] = '0.0.0.0'
settings.DATABASES['default']['PORT'] = '5432'
settings.DATABASES['default']['USER'] = 'postgres'
settings.DATABASES['default']['PASSWORD'] = 'secret123'
settings.DATABASES['default']['NAME'] = 'mypgsqldb'
# settings.DATABASES['default']['ATOMIC_REQUESTS'] = False
# settings.DATABASES['default']['AUTOCOMMIT'] = True
# settings.DATABASES['default']['CONN_MAX_AGE'] = 0
# settings.DATABASES['default']['CONN_HEALTH_CHECKS'] = False
# settings.DATABASES['default']['OPTIONS'] = {}

os.environ["XPRESSDIR"] = "/opt/xpressmp"
os.environ["XPRESS"] = "/opt/xpressmp/bin"
os.environ["LD_LIBRARY_PATH"] = os.environ["XPRESSDIR"] + "/lib"
os.environ["DYLD_LIBRARY_PATH"] = os.environ["XPRESSDIR"] + "/lib"
os.environ["SHLIB_PATH"] = os.environ["XPRESSDIR"] + "/lib"
os.environ["LIBPATH"] = os.environ["XPRESSDIR"] + "/lib"
os.environ["PYTHONPATH"] = os.environ["XPRESSDIR"] + "/lib"
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprs.jar"
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprb.jar" + os.pathsep + os.environ["CLASSPATH"]
os.environ["CLASSPATH"] = os.environ["XPRESSDIR"] + "/lib/xprm.jar" + os.pathsep + os.environ["CLASSPATH"]
os.environ["PATH"] = os.environ["XPRESSDIR"] + "/bin" + os.pathsep + os.environ["PATH"]


import django
django.setup()

from scheduler.models import *
import pulp
from pulp import lpSum, value, XPRESS, GUROBI, PULP_CBC_CMD
from django.db.models import Q
from django.template.loader import render_to_string

from qualifiers.models import *
from common.models import GlobalTeam, GlobalCountry
from scheduler.models import Season, Scenario, Team, DayObj, CountryClash, Country

from qualifiers.draws import groupTeams, optimize_inversions4
from scheduler.solver.tasks.optimize import optimize
from scheduler.solver.tasks.optimize_submodels import ueluecl24_basicmodell_v2

import random
import time
import json
import datetime 
import traceback
import os



import errno
import os
import signal
import functools



user_name = 'md'
user_is_staff = True
runMode = 'Improve'
localsearch_time = 0
RUN_ENV = 'local'
SOLVER = 'xpress'


class TimeoutError(Exception):
    pass

def timeout_wrapper(seconds=10, error_message=os.strerror(errno.ETIME)):
    def decorator(func):
        def _handle_timeout(signum, frame):
            raise TimeoutError(error_message)

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.alarm(seconds)
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result

        return wrapper

    return decorator



@timeout_wrapper(120)
def run_scenario(scenario):
    
    s2 = scenario.id
    
    optimize(task=None, s2=s2, user_name=user_name, user_is_staff=user_is_staff,
        runMode=runMode, localsearch_time=localsearch_time, RUN_ENV=RUN_ENV, solver=SOLVER)


error_filename = f'errors_report_{datetime.datetime.now().strftime("%Y%m%d_%H%M%S")}.json'
filename = f'report_{datetime.datetime.now().strftime("%Y%m%d_%H%M%S")}.json'
with open(f'reports/{error_filename}', mode='w', encoding='utf-8') as f:
    json.dump([], f)
with open(f'reports/{filename}', mode='w', encoding='utf-8') as f:
    json.dump([], f)

seasons = Season.objects.filter(is_hidden=False)

for i,season in enumerate(seasons):
    if len(season.users_customers()) <= 0:
        continue

    for scenario in season.scenarios.filter(is_hidden=False):

        try:
            run_scenario(scenario)
            
            report = {
                'run_id': i,
                'league': season.league.name,
                'season': season.nicename,
                'scenario': scenario.name, 
                'scenario_id': scenario.id, 
                'runMode': runMode,
                'localsearch_time': localsearch_time,
                'info': 'success',
                'message': 'ALL GOOD :-)'
            }
            
        except Exception as e:
            report = {
                'run_id': i,
                'league': season.league.name,
                'season': season.nicename,
                'scenario': scenario.name, 
                'scenario_id': scenario.id, 
                'runMode': runMode,
                'localsearch_time': localsearch_time,
                'info': 'error',
                'exception': repr(e),
                'exception_type':e.__class__.__name__,
                'traceback': f"{traceback.format_exc()}"
            }

            os.system("killall optimizer")
                
            with open(f'reports/{error_filename}') as instancejson:
                instance = json.load(instancejson)
            instance.append(report)        
            with open(f'reports/{error_filename}', mode='w', encoding='utf-8') as instancejson:
                json.dump(instance, instancejson, indent=4)
        
        
        with open(f'reports/{filename}') as instancejson:
            instance = json.load(instancejson)
        instance.append(report)       
        with open(f'reports/{filename}', mode='w', encoding='utf-8') as instancejson:
            json.dump(instance, instancejson, indent=4)

        