__author__ = "Lukas Leufen"
__date__ = '2019-11-25'

import logging
import os
import shutil
import time

from src.helpers import Logger
from src.datastore import DataStoreByScope as DataStoreObject
from src.datastore import NameNotFoundInDataStore
from src.helpers import TimeTracking


class RunEnvironment(object):
    """
    basic run class to measure execution time. Either call this class calling it by 'with' or delete the class instance
    after finishing the measurement. The duration result is logged.
    """

    del_by_exit = False
    data_store = DataStoreObject()
    logger = Logger()

    def __init__(self):
        """
        Starts time tracking automatically and logs as info.
        """
        self.time = TimeTracking()
        logging.info(f"{self.__class__.__name__} started")

    def __del__(self):
        """
        This is the class finalizer. The code is not executed if already called by exit method to prevent duplicated
        logging (__exit__ is always executed before __del__) it this class was used in a with statement.
        """
        if not self.del_by_exit:
            self.time.stop()
            logging.info(f"{self.__class__.__name__} finished after {self.time}")
            self.del_by_exit = True
        if self.__class__.__name__ == "RunEnvironment":
            try:
                new_file = os.path.join(self.data_store.get("experiment_path"), "logging.log")
                shutil.copyfile(self.logger.log_file, new_file)
            except (NameNotFoundInDataStore, FileNotFoundError):
                pass
            self.data_store.clear_data_store()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            logging.error(exc_val, exc_info=(exc_type, exc_val, exc_tb))
        self.__del__()

    @staticmethod
    def do_stuff(length=2):
        time.sleep(length)