from dexy.constants import Constants
import dexy.artifact
import dexy.database
import dexy.introspect
import dexy.utils
import os
import shutil

class Reporter(object):
    ALLREPORTS = True # whether to be included in 'allreports', set to false for reporters with side effects
    REPORTS_DIR = None
    LDIR = Constants.DEFAULT_LDIR
    LFILE = Constants.DEFAULT_LFILE
    ACLASS = Constants.DEFAULT_ACLASS
    DBFILE = Constants.DEFAULT_DBFILE
    DBCLASS = Constants.DEFAULT_DBCLASS
    SAFETY_FILENAME = ".dexy-generated"
    README_FILENAME = "README"

    def create_reports_dir(self, reports_dir):
        safety_filepath = os.path.join(reports_dir, self.SAFETY_FILENAME)
        readme_filepath = os.path.join(reports_dir, self.README_FILENAME)

        if os.path.exists(reports_dir) and not os.path.exists(safety_filepath):
            raise Exception("Please remove directory %s, Dexy wants to put a report here but doesn't want to overwrite anything by accident." % os.path.abspath(reports_dir))
        elif os.path.exists(reports_dir):
            shutil.rmtree(reports_dir)

        os.mkdir(reports_dir)

        with open(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__)
        with open(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 __init__(self, logsdir=LDIR, logfile=LFILE, artifact_class=ACLASS, batch_id=None,
            dbfile=DBFILE, controller=None, dbclass=DBCLASS, hashfunction='md5'):

        self.db = dexy.utils.get_db(dbclass, logsdir=logsdir, dbfile=dbfile)

        if batch_id:
            self.batch_id = batch_id
        else:
            self.batch_id = self.db.max_batch_id()

        self.dbfile = dbfile
        self.log = dexy.utils.get_log('dexy.controller', logsdir=logsdir, logfile=logfile)
        self.log.debug("Reporter %s initialized" % self.__class__.__name__)
        self.logfile = logfile
        self.logsdir = logsdir
        self.hashfunction = hashfunction

        if isinstance(artifact_class, str):
            artifact_classes = dexy.introspect.artifact_classes()
            self.artifact_class = artifact_classes[artifact_class]
        elif issubclass(artifact_class, dexy.artifact.Artifact):
            self.artifact_class = artifact_class
        else:
            raise Exception("expected artifact_class to be class name or class, got %s"  % type(artifact_class))

        if controller:
            self.batch_info = controller.batch_info()
        elif self.batch_id:
            self.batch_info = dexy.utils.load_batch_info(self.batch_id, logsdir)
        else:
            print "warning, no batch id could be detected"
            self.batch_info = None

    def load_batch_artifacts(self):
        db = dexy.utils.get_db(logsdir=self.logsdir, dbfile=self.dbfile)
        refs = db.references_for_batch_id(self.batch_id)
        self.batch_refs = refs
        self.artifacts = dict((r['hashstring'], self.artifact_class.retrieve(r['hashstring'], self.hashfunction)) for r in refs)

    def run(self):
        pass
