from invoke import task
import os
import shutil
import json
from dotenv import load_dotenv, find_dotenv, dotenv_values
import invoke
from datetime import datetime, timedelta
import sys
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
from icecream import ic
from textwrap import dedent
from rich import print as rprint, inspect as rinspect
from time import sleep, time
import re
import subprocess
# region [Constants]
MODULE_NAME = "antistasi_console_log_parser"
THIS_FILE_DIR = os.path.abspath(os.path.dirname(__file__))

GIT_EXE = shutil.which('git.exe')


TEMP_FOLDER = os.path.join(THIS_FILE_DIR, 'temp')
MISC_FOLDER = os.path.join(THIS_FILE_DIR, 'misc')
DOCS_FOLDER = os.path.join(THIS_FILE_DIR, 'docs')
MAIN_MODULE_FOLDER = os.path.join(THIS_FILE_DIR, MODULE_NAME)
LOG_NAME_DATE_TIME_REGEX = re.compile(r"(?P<year>\d\d\d\d).(?P<month>\d+?).(?P<day>\d+).(?P<hour>[012\s]?\d).(?P<minute>[0123456]\d).(?P<second>[0123456]\d)")

IMPORTANT_FOLDER = [TEMP_FOLDER, MISC_FOLDER, DOCS_FOLDER, MAIN_MODULE_FOLDER]

SCRATCH_BOILER = dedent("""
                # region[Imports]

                import os
                import subprocess
                import shutil
                import sys
                from inspect import getmembers, isclass, isfunction
                from pprint import pprint, pformat
                from typing import Union, Dict, Set, List, Tuple
                from datetime import tzinfo, datetime, timezone, timedelta
                from icecream import ic
                import re
                from dotenv import load_dotenv
                from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
                import random
                from functools import wraps, lru_cache, singledispatch, total_ordering, partial
                from contextlib import contextmanager
                from collections import Counter, ChainMap, deque, namedtuple, defaultdict
                from enum import Enum, unique, Flag, auto
                from rich import print as rprint, inspect as rinspect
                from time import time, sleep
                from timeit import Timer, timeit
                from textwrap import dedent
                from gidtools.gidfiles import pathmaker, loadjson, writejson, writeit, readit

                # endregion [Imports]
                """).strip()


# endregion[Constants]


def loadjson(in_file):
    with open(in_file, 'r') as jsonfile:
        _out = json.load(jsonfile)
    return _out


def writejson(in_object, in_file, sort_keys=True, indent=4):
    with open(in_file, 'w') as jsonoutfile:
        json.dump(in_object, jsonoutfile, sort_keys=sort_keys, indent=indent)


def readit(in_file, per_lines=False, in_encoding='utf-8', in_errors=None):

    with open(in_file, 'r', encoding=in_encoding, errors=in_errors) as _rfile:
        _content = _rfile.read()
    if per_lines is True:
        _content = _content.splitlines()

    return _content


def writeit(in_file, in_data, append=False, in_encoding='utf-8', in_errors=None):

    _write_type = 'w' if append is False else 'a'
    with open(in_file, _write_type, encoding=in_encoding, errors=in_errors,) as _wfile:
        _wfile.write(in_data)


def pathmaker(first_segment, *in_path_segments, rev=False):
    _path = first_segment
    _path = os.path.join(_path, *in_path_segments)
    if rev is True or sys.platform not in ['win32', 'linux']:
        return os.path.normpath(_path)
    return os.path.normpath(_path).replace(os.path.sep, '/')


VENV_ACTIVATOR_PATH = pathmaker(THIS_FILE_DIR, '.venv/Scripts/activate.bat', rev=True)
PYINSTALLER_BATCH = pathmaker(THIS_FILE_DIR, 'tools', 'quick_pyinstaller_noconsole.bat')
MAIN_FILE = pathmaker(THIS_FILE_DIR, 'antistasi_console_log_parser', '__main__.py')


def activator_run(c, command, echo=True, **kwargs):
    with c.prefix(VENV_ACTIVATOR_PATH):
        result = c.run(command, echo=echo, **kwargs)
        return result


def create_folder(in_path):
    if os.path.isdir(in_path) is False:
        os.makedirs(in_path)


def clean_create_folder(in_path):
    if os.path.isdir(in_path):
        shutil.rmtree(in_path)
    create_folder(in_path)


def main_dir_from_git():
    cmd = subprocess.run([GIT_EXE, "rev-parse", "--show-toplevel"], capture_output=True, text=True, shell=True, check=True)
    main_dir = pathmaker(cmd.stdout).rstrip('\n')
    if os.path.isdir(main_dir) is False:
        raise FileNotFoundError('Unable to locate main dir of project')
    return main_dir


os.chdir(main_dir_from_git())
for folder_path in IMPORTANT_FOLDER:
    create_folder(folder_path)

SCRATCHES_FOLDER = pathmaker(main_dir_from_git(), 'tools', 'scratches')


def _date_time_from_name(path):
    matched_data = LOG_NAME_DATE_TIME_REGEX.search(os.path.basename(path))
    if matched_data:
        date_time_string = f"{matched_data.group('year')}-{matched_data.group('month')}-{matched_data.group('day')} {matched_data.group('hour')}:{matched_data.group('minute')}:{matched_data.group('second')}"
        date_time = datetime.strptime(date_time_string, "%Y-%m-%d %H:%M:%S")
        return date_time
    else:
        raise RuntimeError(f'unable to find date_time_string in {os.path.basename(path)}')


def get_alternative_name(name, number=0):
    if number == 0:
        mod_name = name
    else:
        mod_name = f"{name}_{number}"

    if mod_name.casefold() in {file.name.split('.')[0].casefold() for file in os.scandir(SCRATCHES_FOLDER) if file.is_file() and file.name.endswith('.py')}:
        return get_alternative_name(name, number + 1)
    return mod_name


@task
def new_scratch(c, prefix=None):
    if os.path.isdir(SCRATCHES_FOLDER) is False:
        os.makedirs(SCRATCHES_FOLDER)
    name = "scratch" if prefix is None else f"{prefix}_scratch"
    file_name = get_alternative_name(name) + '.py'
    full_path = pathmaker(SCRATCHES_FOLDER, file_name)
    with open(full_path, 'w') as f:
        f.write(SCRATCH_BOILER + '\n\n\n\n')
        f.write("if __name__ == '__main__':\n")
        f.write("\tpass\n")


@task
def build(c):
    activator_run(c, f"{PYINSTALLER_BATCH} {MAIN_FILE}")

from invoke import task
import os
import shutil
import json
from dotenv import load_dotenv, find_dotenv, dotenv_values
import invoke
from datetime import datetime, timedelta
import sys
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
from icecream import ic
from textwrap import dedent
from rich import print as rprint, inspect as rinspect
from time import sleep, time
import re
import subprocess
# region [Constants]
MODULE_NAME = "antistasi_console_log_parser"
THIS_FILE_DIR = os.path.abspath(os.path.dirname(__file__))

GIT_EXE = shutil.which('git.exe')


TEMP_FOLDER = os.path.join(THIS_FILE_DIR, 'temp')
MISC_FOLDER = os.path.join(THIS_FILE_DIR, 'misc')
DOCS_FOLDER = os.path.join(THIS_FILE_DIR, 'docs')
MAIN_MODULE_FOLDER = os.path.join(THIS_FILE_DIR, MODULE_NAME)
LOG_NAME_DATE_TIME_REGEX = re.compile(r"(?P<year>\d\d\d\d).(?P<month>\d+?).(?P<day>\d+).(?P<hour>[012\s]?\d).(?P<minute>[0123456]\d).(?P<second>[0123456]\d)")

IMPORTANT_FOLDER = [TEMP_FOLDER, MISC_FOLDER, DOCS_FOLDER, MAIN_MODULE_FOLDER]

SCRATCH_BOILER = dedent("""
                # region[Imports]

                import os
                import subprocess
                import shutil
                import sys
                from inspect import getmembers, isclass, isfunction
                from pprint import pprint, pformat
                from typing import Union, Dict, Set, List, Tuple
                from datetime import tzinfo, datetime, timezone, timedelta
                from icecream import ic
                import re
                from dotenv import load_dotenv
                from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
                import random
                from functools import wraps, lru_cache, singledispatch, total_ordering, partial
                from contextlib import contextmanager
                from collections import Counter, ChainMap, deque, namedtuple, defaultdict
                from enum import Enum, unique, Flag, auto
                from rich import print as rprint, inspect as rinspect
                from time import time, sleep
                from timeit import Timer, timeit
                from textwrap import dedent
                from gidtools.gidfiles import pathmaker, loadjson, writejson, writeit, readit

                # endregion [Imports]
                """).strip()


# endregion[Constants]


def loadjson(in_file):
    with open(in_file, 'r') as jsonfile:
        _out = json.load(jsonfile)
    return _out


def writejson(in_object, in_file, sort_keys=True, indent=4):
    with open(in_file, 'w') as jsonoutfile:
        json.dump(in_object, jsonoutfile, sort_keys=sort_keys, indent=indent)


def readit(in_file, per_lines=False, in_encoding='utf-8', in_errors=None):

    with open(in_file, 'r', encoding=in_encoding, errors=in_errors) as _rfile:
        _content = _rfile.read()
    if per_lines is True:
        _content = _content.splitlines()

    return _content


def writeit(in_file, in_data, append=False, in_encoding='utf-8', in_errors=None):

    _write_type = 'w' if append is False else 'a'
    with open(in_file, _write_type, encoding=in_encoding, errors=in_errors,) as _wfile:
        _wfile.write(in_data)


def pathmaker(first_segment, *in_path_segments, rev=False):
    _path = first_segment
    _path = os.path.join(_path, *in_path_segments)
    if rev is True or sys.platform not in ['win32', 'linux']:
        return os.path.normpath(_path)
    return os.path.normpath(_path).replace(os.path.sep, '/')


VENV_ACTIVATOR_PATH = pathmaker(THIS_FILE_DIR, '.venv/Scripts/activate.bat', rev=True)
PYINSTALLER_BATCH = pathmaker(THIS_FILE_DIR, 'tools', 'quick_pyinstaller_noconsole.bat')
MAIN_FILE = pathmaker(THIS_FILE_DIR, 'antistasi_console_log_parser', '__main__.py')


def activator_run(c, command, echo=True, **kwargs):
    with c.prefix(VENV_ACTIVATOR_PATH):
        result = c.run(command, echo=echo, **kwargs)
        return result


def create_folder(in_path):
    if os.path.isdir(in_path) is False:
        os.makedirs(in_path)


def clean_create_folder(in_path):
    if os.path.isdir(in_path):
        shutil.rmtree(in_path)
    create_folder(in_path)


def main_dir_from_git():
    cmd = subprocess.run([GIT_EXE, "rev-parse", "--show-toplevel"], capture_output=True, text=True, shell=True, check=True)
    main_dir = pathmaker(cmd.stdout).rstrip('\n')
    if os.path.isdir(main_dir) is False:
        raise FileNotFoundError('Unable to locate main dir of project')
    return main_dir


os.chdir(main_dir_from_git())
for folder_path in IMPORTANT_FOLDER:
    create_folder(folder_path)

SCRATCHES_FOLDER = pathmaker(main_dir_from_git(), 'tools', 'scratches')


def _date_time_from_name(path):
    matched_data = LOG_NAME_DATE_TIME_REGEX.search(os.path.basename(path))
    if matched_data:
        date_time_string = f"{matched_data.group('year')}-{matched_data.group('month')}-{matched_data.group('day')} {matched_data.group('hour')}:{matched_data.group('minute')}:{matched_data.group('second')}"
        date_time = datetime.strptime(date_time_string, "%Y-%m-%d %H:%M:%S")
        return date_time
    else:
        raise RuntimeError(f'unable to find date_time_string in {os.path.basename(path)}')


def get_alternative_name(name, number=0):
    if number == 0:
        mod_name = name
    else:
        mod_name = f"{name}_{number}"

    if mod_name.casefold() in {file.name.split('.')[0].casefold() for file in os.scandir(SCRATCHES_FOLDER) if file.is_file() and file.name.endswith('.py')}:
        return get_alternative_name(name, number + 1)
    return mod_name


@task
def new_scratch(c, prefix=None):
    if os.path.isdir(SCRATCHES_FOLDER) is False:
        os.makedirs(SCRATCHES_FOLDER)
    name = "scratch" if prefix is None else f"{prefix}_scratch"
    file_name = get_alternative_name(name) + '.py'
    full_path = pathmaker(SCRATCHES_FOLDER, file_name)
    with open(full_path, 'w') as f:
        f.write(SCRATCH_BOILER + '\n\n\n\n')
        f.write("if __name__ == '__main__':\n")
        f.write("\tpass\n")


@task
def build(c):
    activator_run(c, f"{PYINSTALLER_BATCH} {MAIN_FILE}")

# region [Constants] # region[Imports]                  import os                 import subprocess                 import shutil                 import sys                 from inspect import getmembers, isclass, isfunction                 from pprint import pprint, pformat                 from typing import Union, Dict, Set, List, Tuple                 from datetime import tzinfo, datetime, timezone, timedelta                 from icecream import ic                 import re                 from dotenv import load_dotenv                 from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor                 import random                 from functools import wraps, lru_cache, singledispatch, total_ordering, partial                 from contextlib import contextmanager                 from collections import Counter, ChainMap, deque, namedtuple, defaultdict                 from enum import Enum, unique, Flag, auto                 from rich import print as rprint, inspect as rinspect                 from time import time, sleep                 from timeit import Timer, timeit                 from textwrap import dedent                 from gidtools.gidfiles import pathmaker, loadjson, writejson, writeit, readit                  # endregion [Imports] # endregion[Constants]