"""calendar of learning, all in issuedates"""

import sys

import dater

from plumi import Plumi
from ishus import Ishus
from otria import Otria
from recon import Recon
from xpafs import Xpafs


class Caler:

    def __init__(self, erimp, do_verbose=False):
        self.e = erimp
        self.ishus = Ishus(self.e)
        self.plumi = Plumi(self.e)
        self.otria = Otria(self.e)
        self.recon = Recon(self.e)
        self.xpafs = Xpafs(self.e)
        if 'traspi' not in self.e.conf:
            print("caler: no traspi",
                  file=sys.stderr)
        self.traspi = int(self.e.conf['traspi'])
        self.grospi = None
        if 'grospi' in self.e.conf:
            self.grospi = int(self.e.conf['grospi'])
        self.train_issues = None
        self.do_verbose = do_verbose
        return None

    def train_dafus(self, repcode, do_check_recon=True):
        """by default we check the recon for manual start setting"""
        # # this ought to take account of the forpis
        # # needs to be checked
        dafus = self.plumi.dafus(repcode, do_verbose=self.do_verbose)
        if len(list(dafus)) <= self.traspi:
            return dafus
        while len(list(dafus)) > self.traspi:
            # print(len(list(dafus)))
            # print(self.traspi)
            # quit()
            first_date = list(dafus)[0]
            del dafus[first_date]
        if not do_check_recon:
            return dafus
        # #  a train date that is set manually
        start_train = self.start_train(repcode)
        if start_train is None:
            return dafus
        reduced_dafus = {}
        for issuedate in dafus:
            if issuedate < start_train:
                continue
            reduced_dafus[issuedate] = dafus[issuedate]
        return reduced_dafus

    def get_issues_in_train(self):
        """return all the issues we need training for and report to blame"""
        if self.train_issues is not None:
            return self.train_issues
        repcodes = self.otria.by_timely()
        issues_reports = {}
        for repcode in repcodes:
            # # don't check the recon here for speed
            dafus = self.train_dafus(repcode, do_check_recon=False)
            for issuedate in dafus:
                issues_reports[issuedate] = repcode
        self.train_issues = issues_reports
        return issues_reports

    def get_didspi(self):
        issues_reports = self.get_issues_in_train()
        return len(issues_reports.keys())

    def is_issue_in_train(self, issuedate):
        if self.train_issues is None:
            self.get_issues_in_train()
        if issuedate in self.train_issues:
            return True
        return False

    def earliest_issue_in_train(self):
        self.get_issues_in_train()
        earliest_issue = sorted(self.train_issues)[0]
        print(earliest_issue + ' ' + self.train_issues[earliest_issue])

    def start_train(self, repcode):
        """a training start set in the report configuration"""
        recon = self.recon.doc(repcode)
        if recon is None:
            print(f"train can not read the recon for {repcode}",
                  file=sys.stderr)
        found = self.xpafs.none_or_one(recon, '//e:start_train/text()')
        # # it does not matter whether found is an issuuedate
        return found

    def is_report_mature(self, repcode):
        #        if 'traspi' not in self.e.conf:
        #            return False
        sent_dir = self.e.report[repcode].dirs['sent']
        count_issues_sent = len(self.e.d.lasts(sent_dir))
        # print(str(count_issues_sent) + ' o ' + str(self.traspi))
        if count_issues_sent < self.traspi:
            return False
        return True

    def should_report_have_grond(self, repcode):
        #        if 'traspi' not in self.e.conf:
        #            return False
        if self.grospi is None:
            return False
        sent_dir = self.e.report[repcode].dirs['sent']
        count_issues_sent = len(self.e.d.lasts(sent_dir))
        if count_issues_sent < self.grospi:
            return False
        return True

    def is_it_in_train(self, issuedate):
        if issuedate == dater.today():
            return True
        if issuedate == dater.tonight():
            return True
        # # fills self.train_issues
        self.get_issues_in_train()
        if issuedate in self.train_issues:
            return True
        return False
