from dexy.utils import file_exists
import dexy.plugin
import os
import shutil

class Reporter(dexy.plugin.Plugin):
    """
    Base class for types of reporter.
    """
    aliases = []
    __metaclass__ = dexy.plugin.PluginMeta

    _settings = {
            "default" : ("Whether to run this report by default. Should be False for reports with side effects.", True),
            "dir" : ("Top-level directory in which report will be stored", None),
            "run-for-wrapper-states" : ("List of states in which this report can be run.", ["ran"]),
            "readme-filename" : ("Name of README file.", "README"),
            "safety-filename" : ("Name of a file which will be created in generated dir, and checked before generated dir is removed.", ".dexy-generated"),
            }
    _UNSET = []

    def is_active(self):
        return True

    def key_for_log(self):
        return "reporter:%s" % self.aliases[0]

    def log_debug(self, message):
        self.wrapper.log.debug("%s: %s" % (self.key_for_log(), message))

    def log_info(self, message):
        self.wrapper.log.info("%s: %s" % (self.key_for_log(), message))

    def log_warn(self, message):
        self.wrapper.log.warn("%s: %s" % (self.key_for_log(), message))

    def safety_filepath(self):
        return os.path.join(self.setting('dir'), self.setting('safety-filename'))

    def readme_filepath(self):
        return os.path.join(self.setting('dir'), self.setting('readme-filename'))

    def write_safety_file(self):
        with open(self.safety_filepath(), "w") as f:
            f.write("""
            This directory was generated by the %s Dexy Reporter and
            may be deleted without notice.\n\n""" % self.__class__.__name__)

    def write_readme_file(self):
        with open(self.readme_filepath(), "w") as f:
            f.write("""
            This directory was generated by the %s Dexy Reporter and
            may be deleted without notice.\n\n""" % self.__class__.__name__)

    def create_reports_dir(self):
        if not self.setting('dir'):
            return False

        self.remove_reports_dir(keep_empty_dir=True)

        if not file_exists(self.setting('dir')):
            os.mkdir(self.setting('dir'))

        self.write_safety_file()
        self.write_readme_file()

    def remove_reports_dir(self, keep_empty_dir=False):
        if not self.setting('dir'):
            return False

        if file_exists(self.setting('dir')) and not file_exists(self.safety_filepath()):
            msg = "Please remove directory %s, Dexy wants to write a report here but there's already a file or directory in this location."
            msgargs = (os.path.abspath(self.setting('dir')))
            raise dexy.exceptions.UserFeedback(msg % msgargs)
        elif file_exists(self.setting('dir')):
            if keep_empty_dir:
                # Does not remove the base directory, useful if you are running
                # a process (like 'dexy serve') from inside that directory
                for f in os.listdir(self.setting('dir')):
                    path = os.path.join(self.setting('dir'), f)
                    if os.path.isdir(path):
                        shutil.rmtree(path)
                    else:
                        os.remove(path)
                self.write_safety_file()
            else:
                shutil.rmtree(self.setting('dir'))

    def run(self, wrapper):
        pass
