import datetime

import mock

from rdr_service import clock
from rdr_service.dao.genomics_dao import GenomicSetDao, GenomicSetMemberDao
from rdr_service.dao.participant_dao import ParticipantDao
from rdr_service.dao.participant_summary_dao import ParticipantSummaryDao
from rdr_service.genomic.validation import validate_and_update_genomic_set_by_id
from rdr_service.model.genomics import (
    GenomicSet,
    GenomicSetMember,
)
from rdr_service.model.participant import Participant
from rdr_service.participant_enums import SampleStatus, WithdrawalStatus
from rdr_service.genomic_enums import GenomicSetStatus, GenomicSetMemberStatus, GenomicValidationFlag
from tests.helpers.unittest_base import BaseTestCase


class GenomicSetValidationBaseTestCase(BaseTestCase):
    def setUp(self):
        super(GenomicSetValidationBaseTestCase, self).setUp()
        self.participant_dao = ParticipantDao()
        self.summary_dao = ParticipantSummaryDao()
        self.genomic_set_dao = GenomicSetDao()
        self.genomic_member_dao = GenomicSetMemberDao()
        self._participant_i = 0
        self.setup_data()

    def setup_data(self):
        pass

    def make_participant(self, **kwargs):
        """
    Make a participant with custom settings.
    default should create a valid participant.
    """
        i = self._participant_i
        self._participant_i += 1
        participant = Participant(participantId=i, biobankId=i, **kwargs)
        self.participant_dao.insert(participant)
        return participant

    def make_summary(self, participant, **override_kwargs):
        """
    Make a summary with custom settings.
    default should create a valid summary.
    """
        valid_kwargs = dict(
            participantId=participant.participantId,
            biobankId=participant.biobankId,
            withdrawalStatus=participant.withdrawalStatus,
            dateOfBirth=datetime.datetime(2000, 1, 1),
            firstName="foo",
            lastName="bar",
            zipCode="12345",
            sampleStatus1ED04=SampleStatus.RECEIVED,
            sampleStatus1SAL2=SampleStatus.RECEIVED,
            samplesToIsolateDNA=SampleStatus.RECEIVED,
            consentForStudyEnrollmentTime=datetime.datetime(2019, 1, 1),
            participantOrigin='example'
        )
        kwargs = dict(valid_kwargs, **override_kwargs)
        summary = self.data_generator._participant_summary_with_defaults(**kwargs)
        self.summary_dao.insert(summary)
        return summary

    def make_genomic_set(self, **override_kwargs):
        """
    Make a genomic set with custom settings.
    default should create a valid set.
    """
        valid_kwargs = dict(
            genomicSetName="foo",
            genomicSetCriteria="something",
            genomicSetVersion=1,
            genomicSetStatus=GenomicSetStatus.UNSET,
        )
        kwargs = dict(valid_kwargs, **override_kwargs)
        genomic_set = GenomicSet(**kwargs)
        self.genomic_set_dao.insert(genomic_set)
        return genomic_set

    def make_genomic_member(self, genomic_set, participant, **override_kwargs):
        """
    Make a genomic member with custom settings.
    default should create a valid member.
    """
        valid_kwargs = dict(
            genomicSetId=genomic_set.id,
            participantId=participant.participantId,
            sexAtBirth="F",
            biobankId=participant.biobankId,
        )
        kwargs = dict(valid_kwargs, **override_kwargs)
        member = GenomicSetMember(**kwargs)
        self.genomic_member_dao.insert(member)
        return member


# TODO: represent in new test suite
class GenomicSetMemberValidationTestCase(GenomicSetValidationBaseTestCase):
    def test_test_defaults_are_valid(self):
        participant = self.make_participant()
        self.make_summary(participant)
        genomic_set = self.make_genomic_set()
        member = self.make_genomic_member(genomic_set, participant)
        validate_and_update_genomic_set_by_id(genomic_set.id)
        current_member = self.genomic_member_dao.get(member.id)
        self.assertEqual(current_member.validationStatus, GenomicSetMemberStatus.VALID)
        current_set = self.genomic_set_dao.get(genomic_set.id)
        self.assertEqual(current_set.genomicSetStatus, GenomicSetStatus.VALID)

    def test_duplicate(self):
        participant = self.make_participant()
        self.make_summary(participant)
        genomic_set_a = self.make_genomic_set(genomicSetName="A", genomicSetStatus=GenomicSetStatus.VALID)
        self.make_genomic_member(genomic_set_a, participant)
        genomic_set_b = self.make_genomic_set(genomicSetName="B")
        member_b = self.make_genomic_member(genomic_set_b, participant)