# -*- coding: utf-8 -*-
import logging
from typing import List

from cg.store import models, Store
from cg.apps.stats import StatsAPI
from cg.apps.hk import HousekeeperAPI

LOG = logging.getLogger(__name__)


class TransferFlowcell():

    def __init__(self, db: Store, stats_api: StatsAPI, hk_api: HousekeeperAPI=None):
        self.db = db
        self.stats = stats_api
        self.hk = hk_api

    def transfer(self, flowcell_name: str, store: bool=True) -> models.Flowcell:
        """Populate the database with the information."""
        if store and self.hk.tag('fastq') is None:
            self.hk.add_commit(self.hk.new_tag('fastq'))
        if store and self.hk.tag(flowcell_name) is None:
            self.hk.add_commit(self.hk.new_tag(flowcell_name))
        stats_data = self.stats.flowcell(flowcell_name)
        flowcell_obj = self.db.flowcell(flowcell_name)
        if flowcell_obj is None:
            flowcell_obj = self.db.add_flowcell(
                name=flowcell_name,
                sequencer=stats_data['sequencer'],
                sequencer_type=stats_data['sequencer_type'],
                date=stats_data['date'],
            )
        flowcell_obj.status = 'ondisk'
        for sample_data in stats_data['samples']:
            LOG.debug(f"adding reads/fastqs to sample: {sample_data['name']}")
            sample_obj = self.db.sample(sample_data['name'])
            if sample_obj is None:
                LOG.warning(f"unable to find sample: {sample_data['name']}")
                continue

            if store:
                self.store_fastqs(
                    sample=sample_obj.internal_id,
                    flowcell=flowcell_name,
                    fastq_files=sample_data['fastqs']
                )

            sample_obj.reads = sample_data['reads']
            enough_reads = (sample_obj.reads >
                            sample_obj.application_version.application.expected_reads)
            newest_date = ((sample_obj.sequenced_at is None) or
                           (flowcell_obj.sequenced_at > sample_obj.sequenced_at))
            if enough_reads and newest_date:
                sample_obj.sequenced_at = flowcell_obj.sequenced_at
            flowcell_obj.samples.append(sample_obj)
            LOG.info(f"added reads to sample: {sample_data['name']} - {sample_data['reads']} "
                     f"[{'DONE' if enough_reads else 'NOT DONE'}]")

        return flowcell_obj

    def store_fastqs(self, sample: str, flowcell: str, fastq_files: List[str]):
        """Store FASTQ files for a sample in housekeeper."""
        hk_bundle = self.hk.bundle(sample)
        if hk_bundle is None:
            hk_bundle = self.hk.new_bundle(sample)
            self.hk.add_commit(hk_bundle)
            new_version = self.hk.new_version(created_at=hk_bundle.created_at)
            hk_bundle.versions.append(new_version)
            self.hk.commit()
            LOG.info(f"added new Housekeeper bundle: {hk_bundle.name}")

        with self.hk.session.no_autoflush:
            hk_version = hk_bundle.versions[0]
            for fastq_file in fastq_files:
                if self.hk.files(path=fastq_file).first() is None:
                    LOG.info(f"found FASTQ file: {fastq_file}")
                    tags = [self.hk.tag('fastq'), self.hk.tag(flowcell)]
                    new_file = self.hk.new_file(path=fastq_file, tags=tags)
                    hk_version.files.append(new_file)
            self.hk.commit()
