import os
import logging

import pytest

TRAVIS = os.getenv('TRAVIS')

log = logging.getLogger(__name__)

def test_variant(real_variant_database, variant_objs, case_obj):
    """"Test querying a variant"""
    adapter = real_variant_database
    test_variant = list(variant_objs)[0]

    # try to collect the variant from database using its document_id:
    variant_a = adapter.variant(document_id=test_variant['_id'])
    assert variant_a

    # try to collect the variant from database using its document_id and case id:
    variant_b = adapter.variant(document_id=test_variant['variant_id'], case_id=case_obj['_id'])
    assert variant_b
    # it should be the same variant as before:
    assert variant_a == variant_b

    # try to collect the variant from database using its case id and simple_id:
    variant_c = adapter.variant(simple_id=test_variant['simple_id'], case_id=case_obj['_id'])
    assert variant_c
    # it should be the same as the other 2 variants:
    assert variant_c == variant_a


def test_query_all_gene_variants(real_variant_database):
    """"Test querying gene variants using gene symbol."""
    adapter = real_variant_database

    ## GIVEN a populated database with variants in a certain gene
    hgnc_id = 3233
    gene_obj = adapter.hgnc_gene(hgnc_id)
    assert gene_obj
    # and a valid gene_symbol
    gene_symbol = gene_obj['hgnc_symbol']
    assert gene_symbol

    # direct query fpr
    res = adapter.variant_collection.find({
        '$and': [{'hgnc_symbols': gene_symbol}, {'rank_score': {'$gte': 5}},
                 {'category': 'snv'}, {'variant_type': 'clinical'}]} )
    nr_high_ranked_variants_in_gene = sum(1 for i in res)
    log.info("Number of high ranked variants in %s: %s", gene_symbol, nr_high_ranked_variants_in_gene)

    assert nr_high_ranked_variants_in_gene > 0

    # GIVEN a query on the correct format, corresponding to web form input
    gene_variants_query = {}
    gene_variants_query['rank_score'] = 5
    gene_variants_query['hgnc_symbols'] = [gene_symbol]

    # THEN the same number of variants should be returned by the query function
    result = adapter.gene_variants(query=gene_variants_query, nr_of_variants=-1)
    assert sum(1 for i in result) == nr_high_ranked_variants_in_gene

def test_load_variants(real_populated_database, variant_objs, case_obj):
    """Test to load variants into a mongo database"""
    adapter = real_populated_database
    case_id = case_obj['_id']
    # Make sure that there are no variants in the database
    # GIVEN a populated database without any variants
    res = adapter.variants(case_id=case_id, nr_of_variants=-1)
    assert sum(1 for i in res) == 0

    # WHEN adding a number of variants
    for index, variant_obj in enumerate(variant_objs):
        # print(variant_obj)
        adapter.load_variant(variant_obj)

    # THEN the same number of variants should have been loaded
    result = adapter.variants(case_id=case_id, nr_of_variants=-1)
    nr_variants = sum(1 for i in result)
    log.info("Number of variants loaded:%s", nr_variants)
    assert nr_variants == index + 1

def test_load_sv_variants(real_populated_database, sv_variant_objs, case_obj):
    """Test to load variants into a mongo database"""
    adapter = real_populated_database
    case_id = case_obj['_id']

    # GIVEN a populated database without any sv variants
    res = adapter.variants(case_id=case_id, nr_of_variants=-1)
    assert sum(1 for i in res) == 0

    # WHEN adding a number of sv variants
    for index, variant_obj in enumerate(sv_variant_objs):
        adapter.load_variant(variant_obj)

    # THEN the same number of SV variants should have been loaded
    result = adapter.variants(case_id=case_id, nr_of_variants=-1, category='sv')
    assert sum(1 for i in result) == index + 1


def test_load_all_variants(real_populated_database, case_obj):
    adapter = real_populated_database
    case_id = case_obj['_id']

    ## GIVEN a populated database without any variants
    res = adapter.variants(case_id=case_id, nr_of_variants=-1)
    assert sum(1 for i in res) == 0

    ## WHEN loading all variants into the database
    nr_loaded = adapter.load_variants(case_obj=case_obj, variant_type='clinical',
                          category='snv', rank_threshold=None, chrom=None,
                          start=None, end=None, gene_obj=None)

    # THEN the same number of SV variants should have been loaded
    result = adapter.variants(case_id=case_id, nr_of_variants=-1, category='snv')

    assert nr_loaded == sum(1 for i in result)

def test_load_whole_gene(real_populated_database, variant_objs, case_obj):
    adapter = real_populated_database
    case_id = case_obj['_id']

    res = adapter.variants(case_id=case_id, nr_of_variants=-1)
    assert sum(1 for i in res) == 0

    nr_loaded = adapter.load_variants(case_obj=case_obj, variant_type='clinical',
                          category='snv', rank_threshold=None, chrom=None,
                          start=None, end=None, gene_obj=None)

    ## GIVEN a populated database with variants in a certain gene
    hgnc_id = 3233
    gene_obj = adapter.hgnc_gene(hgnc_id)
    assert gene_obj
    res = adapter.variant_collection.find({'hgnc_ids': hgnc_id})
    nr_variants_in_gene = sum(1 for i in res)

    ## WHEN loading all variants for that gene
    nr_loaded = adapter.load_variants(case_obj=case_obj, variant_type='clinical',
                          category='snv', rank_threshold=None, chrom=None,
                          start=None, end=None, gene_obj=gene_obj)

    res = adapter.variant_collection.find({'hgnc_ids': hgnc_id})
    new_nr_variants_in_gene = sum(1 for i in res)

    ## Then assert that the other variants where loaded
    assert new_nr_variants_in_gene > nr_variants_in_gene

def test_load_coordinates(real_populated_database, variant_objs, case_obj):
    adapter = real_populated_database
    case_id = case_obj['_id']

    res = adapter.variants(case_id=case_id, nr_of_variants=-1)
    assert sum(1 for i in res) == 0

    nr_loaded = adapter.load_variants(case_obj=case_obj, variant_type='clinical',
                          category='snv', rank_threshold=None, chrom=None,
                          start=None, end=None, gene_obj=None)

    ## GIVEN a populated database with variants in a certain gene
    hgnc_id = 3233
    gene_obj = adapter.hgnc_gene(hgnc_id)
    assert gene_obj
    res = adapter.variant_collection.find({'hgnc_ids': hgnc_id})
    nr_variants_in_gene = sum(1 for i in res)

    ## WHEN loading all variants for that gene
    nr_loaded = adapter.load_variants(case_obj=case_obj, variant_type='clinical',
                          category='snv', rank_threshold=None, chrom=gene_obj['chromosome'],
                          start=gene_obj['start'], end=gene_obj['end'], gene_obj=None)

    res = adapter.variant_collection.find({'hgnc_ids': hgnc_id})
    new_nr_variants_in_gene = sum(1 for i in res)

    ## Then assert that the other variants where loaded
    assert new_nr_variants_in_gene > nr_variants_in_gene

@pytest.mark.skipif(TRAVIS,
                    reason="Tempfiles seems to be problematic on travis")
def test_get_region_vcf(populated_database, case_obj):
    print('Travis', TRAVIS, type(TRAVIS))
    adapter = populated_database
    case_id = case_obj['_id']

    file_name = adapter.get_region_vcf(case_obj, chrom=None, start=None, end=None,
                       gene_obj=None, variant_type='clinical', category='snv',
                       rank_threshold=None)
    ## GIVEN a populated database with variants in a certain gene
    nr_variants = 0
    with open(file_name, 'r') as f:
        for line in f:
            if not line.startswith('#'):
                nr_variants += 1

    os.remove(file_name)

    assert nr_variants > 0
