"""united seeds and pills"""

# import glob
import os
import sys

import filer

from caler import Caler
from fitli import Fitli
from ishus import Ishus
from lopve import Lopve
from resip import Resip
from sigsi import Sigsi
from sipil import Sipil
from vemli import Vemli


class Usipi:

    def __init__(self, erimp, do_verbose=False):
        """united seeds and pills"""
        self.e = erimp
        # # the usipi is only used with seeds
        if 'is_seedable' not in self.e.conf:
            return None
        self.do_verbose = do_verbose
        # self.folder = Folder(erimp)
        # # the data as in the old version
        self.data = {}
        self.caler = Caler(erimp)
        self.fitli = Fitli(erimp)
        self.sigsi = Sigsi(erimp)
        self.ishus = Ishus(erimp)
        self.lopve = Lopve(erimp)
        self.vemli = Vemli(erimp)
        self.sipil = Sipil(erimp)
        self.resip = Resip(erimp)
        #self.last_sigfi = self.sigsi.get_last()
        #if self.last_sigfi is None:
        #    return None
        self.last_sigfi = self.fitli.train_sig()
        self.i_need_to_write = False
        # # a structure meant to ensure we don't get papids twice
        self.taken_papids = {}
        # # status by repcode
        self.status = {}
        # # samel by repcode
        self.samel = {}
        # # seeds per repcode
        self.seeds = {}
        # # pills per repcode
        self.pills = {}
        # # fufis from sidpil
        self.fufis = {}
        # # data as in the new version
        self.report = {}
        return None

    def get_sidpils(self, repcode, cut_pills=0):
        """get sidpils, for a report in 'l'"""
        is_lovpe_rebuilt = False
        if 'is_seedable' not in self.e.conf:
            print("usipi: I should not have been called for this erimp",
                  file=sys.stderr)
            return None
        if self.caler.is_report_mature(repcode):
            print(f"usipi: I should not have been called for mature {repcode}",
                  file=sys.stderr)
            return {'l': {}}
        self.fufis[repcode] = self.sipil.set_fufis(repcode)
        seedc_fufi = self.fufis[repcode]['seedc']
        if not os.path.isfile(seedc_fufi):
            print(f"usip has no seed configaration {seedc_fufi}")
            return {'l': {}}
        if repcode not in self.status:
            self.status[repcode] = self.get_status(repcode, cut_pills)
        if repcode not in self.samel:
            self.samel[repcode] = self.get_samel(repcode)
        self.report[repcode] = {}
        # # self.fufis[repcode] = self.sipil.set_fufis(repcode)
        out = self.lopve.build_report(repcode, cut_pills=cut_pills)
        if out is None:
            print("usipi has no lopve")
        self.taken_papids[repcode] = {}
        # # actual vemli lines
        self.report[repcode]['l'] = {}
        # # if we have lopve
        if os.path.isfile(self.fufis[repcode]['lopve']):
            lopve_fufi = self.fufis[repcode]['lopve']
            lopve_vemlis = filer.load(lopve_fufi)
            self.taken_papids[repcode] = {}
            # # actual vemli lines
            self.report[repcode]['l'] = {}
            # # local vemlis
            for papid in lopve_vemlis:
                if papid not in self.status[repcode]:
                    # # this happens for a pill that is expired
                    print(f"usipi: local papid {papid} is expired")
                    continue
                if self.status[repcode][papid][-1] == 'i':
                    print(f"usipi: internal sipil {papid} in lopve",
                          file=sys.stderr)
                    continue
                self.report[repcode]['l'][papid] = lopve_vemlis[papid]
                self.taken_papids[repcode][papid] = 1
        #  # global (in didspi) vemlis, run through the samel
        for issuedate in self.samel[repcode]:
            for papid in self.samel[repcode][issuedate]:
                if self.status[repcode][papid][-1] != 'i':
                    print(f"usipi: external sipil {papid} in samel",
                          file=sys.stderr)
                    continue
                vemli_fufi = self.vemli.out_fufi(issuedate, self.last_sigfi)
                issue_vemlis = filer.load(vemli_fufi)
                if papid not in issue_vemlis:
                    msg = f"usipi: {papid} ought to be in the "
                    msg += f"vemlis of {issuedate}"
                    print(msg, file=sys.stderr)
                    continue
                pflag = self.status[repcode][papid][0]
                vemli = issue_vemlis[papid] + f" {issuedate} {pflag}"
                self.report[repcode]['l'][papid] = vemli
        # print(self.report[repcode]['l'])
        sidpils = {}
        sidpils['l'] = {}
        for papid in self.report[repcode]['l']:
            sidpils['l'][papid] = self.report[repcode]['l'][papid]
        return sidpils

    def get_status(self, repcode, cut_pills=0):
        """the papids and their status with repect to lovpe"""
        fufis = self.sipil.set_fufis(repcode)
        if not os.path.isfile(fufis['seedc']):
            return None
        status = {}
        sidis_fufi = fufis['sidis']
        if not os.path.isfile(sidis_fufi):
            # # this should have been done by bin/start
            self.lopve.build_report(repcode)
        seed_issues = filer.load(fufis['sidis'])
        if seed_issues is None:
            seed_issues = {}
        # # let us do the status
        for papid in seed_issues:
            issuedate = seed_issues[papid]
            if issuedate is None:
                status[papid] = 'sx'
            # # in didspi
            elif self.caler.is_it_in_train(issuedate):
                status[papid] = 'si'
            # # out of didspi
            else:
                status[papid] = 'so'
        self.seeds[repcode] = seed_issues
        # 2 # pills
        pill_issues = self.resip.harvest(repcode, cut_pills)
        if pill_issues is None:
            pill_issues = {}
        for papid in pill_issues:
            issuedate = pill_issues[papid]
            if issuedate is None:
                status[papid] = 'px'
            # # in didspi
            elif self.caler.is_it_in_train(issuedate):
                status[papid] = 'pi'
            # # out of didspi
            else:
                status[papid] = 'po'
        self.pills[repcode] = pill_issues
        return status

    def get_samel(self, repcode):
        samel = {}
        # # self.status, self.pills, and self.seeds
        # # created by running self.get_status
        for papid in self.status[repcode]:
            # # if net internal, skipe
            if self.status[repcode][papid][-1] != 'i':
                continue
            if self.status[repcode][papid] == 'si':
                issuedate = self.seeds[repcode][papid]
            else:
                issuedate = self.pills[repcode][papid]
            if issuedate not in samel:
                samel[issuedate] = []
            samel[issuedate].append(papid)
        self.samel[repcode] = samel
        return samel

    def write_train(self, train_file, repcode, papids,
                    cut_pills=0):
        if 'is_seedable' not in self.e.conf:
            return papids
        if self.caler.is_report_mature(repcode):
            print(f"usipi writes nothing for mature {repcode}")
            return papids
        sidpils = self.get_sidpils(repcode, cut_pills=cut_pills)
        if sidpils is None:
            return papids
        vemst = ''
        for papid in sidpils['l']:
            if papid in papids:
                status = papids[papid]
                print(f"usipi skips seen {papid} of {status}")
                continue
            papids[papid] = self.status[repcode][papid]
            vemst += '+1 ' + sidpils['l'][papid] + '\n'
        train_file.write(vemst)
        return papids
