import pytest
import os.path
import pandas as pd
from sqlalchemy import text
from bioleach.env import BIOLEACH_READS_DIR, BIOLEACH_ORGANISMS_DIR
from bioleach.database import (
    fetch_sra_metadata,
    load_organisms_metadata,
    create_pipeline_database
)


def test_sra_metadata():
    _, _, bioleach_biosamples = fetch_sra_metadata()
    assert next(bioleach_biosamples)[0] == 'SAMN44105223'


def test_organisms_metadata():
    _, organisms = load_organisms_metadata()
    assert next(organisms)[0] == 'Acidithiobacillales_thiooxidans_53_22'


def test_create_source_database_sqlite(source_database_engine_sqlite):
    df_bioproject = pd.read_sql("SELECT * FROM bioproject", source_database_engine_sqlite)
    assert (len(df_bioproject.index), len(df_bioproject.columns)) == (1, 5)
    assert df_bioproject.loc[0, 'id'] == 1
    assert df_bioproject.loc[0, 'bioproject_accession'] == 'PRJNA1170356'
    assert df_bioproject.loc[0, 'study_accession'] == 'SRP537212'
    df_biosample = pd.read_sql("SELECT * FROM biosample", source_database_engine_sqlite)
    assert (len(df_biosample.index), len(df_biosample.columns)) == (6, 25)
    assert df_biosample.loc[0, 'id'] == 1
    assert df_biosample.loc[0, 'biosample_accession'] == 'SAMN44105223'
    assert df_biosample.loc[0, 'fastq_prefix'] == os.path.join(BIOLEACH_READS_DIR, 'SRR30914511')
    assert df_biosample.loc[0, 'bioproject_id'] == 1
    df_organism = pd.read_sql("SELECT * FROM organism", source_database_engine_sqlite)
    assert (len(df_organism.index), len(df_organism.columns)) == (24, 5)
    assert df_organism.loc[0, 'id'] == 1
    assert df_organism.loc[0, 'organism'] == 'Acidithiobacillales_thiooxidans_53_22'
    assert df_organism.loc[0, 'bioproject'] == 'PRJNA1170356'
    assert df_organism.loc[0, 'contigs'] == os.path.join(BIOLEACH_ORGANISMS_DIR, 'Acidithiobacillales_thiooxidans_53_22.contigs.fa.gz')
    assert df_organism.loc[0, 'bioproject_id'] == 1

@pytest.mark.mysql
def test_create_source_database_mysql(source_database_engine_mysql):
    df_bioproject = pd.read_sql("SELECT * FROM bioproject", source_database_engine_mysql)
    assert (len(df_bioproject.index), len(df_bioproject.columns)) == (1, 5)
    assert df_bioproject.loc[0, 'id'] == 1
    assert df_bioproject.loc[0, 'bioproject_accession'] == 'PRJNA1170356'
    assert df_bioproject.loc[0, 'study_accession'] == 'SRP537212'
    df_biosample = pd.read_sql("SELECT * FROM biosample", source_database_engine_mysql)
    assert (len(df_biosample.index), len(df_biosample.columns)) == (6, 25)
    assert df_biosample.loc[0, 'id'] == 1
    assert df_biosample.loc[0, 'biosample_accession'] == 'SAMN44105223'
    assert df_biosample.loc[0, 'fastq_prefix'] == os.path.join(BIOLEACH_READS_DIR, 'SRR30914511')
    assert df_biosample.loc[0, 'bioproject_id'] == 1
    df_organism = pd.read_sql("SELECT * FROM organism", source_database_engine_mysql)
    assert (len(df_organism.index), len(df_organism.columns)) == (24, 5)
    assert df_organism.loc[0, 'id'] == 1
    assert df_organism.loc[0, 'organism'] == 'Acidithiobacillales_thiooxidans_53_22'
    assert df_organism.loc[0, 'bioproject'] == 'PRJNA1170356'
    assert df_organism.loc[0, 'contigs'] == os.path.join(BIOLEACH_ORGANISMS_DIR, 'Acidithiobacillales_thiooxidans_53_22.contigs.fa.gz')
    assert df_organism.loc[0, 'bioproject_id'] == 1
    with source_database_engine_mysql.connect() as conn_source:
        conn_source.execute(text('DROP DATABASE test_bioleach_source'))
        conn_source.commit()


def test_create_pipeline_database_sqlite(source_database_engine_sqlite):
    engine_pipeline = create_pipeline_database(
        source_database_engine_sqlite,
        accessions=['SRR30914511'],
        dialect='sqlite',
        database=":memory:"
    )
    df_pipeline = pd.read_sql("SELECT * FROM pipeline_accessions", engine_pipeline)
    assert df_pipeline.loc[0, 'id'] == 1
    assert df_pipeline.loc[0, 'experiment_accession'] == 'SRX26317792'
    assert df_pipeline.loc[0, 'sample_accession'] == 'SRS22845390'
    assert df_pipeline.loc[0, 'run_accession'] == 'SRR30914511'
    assert df_pipeline.loc[0, 'fastq_prefix'] == os.path.join(BIOLEACH_READS_DIR, 'SRR30914511')

@pytest.mark.mysql
def test_create_pipeline_database_mysql(source_database_engine_mysql):
    engine_pipeline = create_pipeline_database(
        source_database_engine_mysql,
        accessions=['SRR30914511'],
        dialect='mysql',
        database="test_bioleach_pipeline"
    )
    df_pipeline = pd.read_sql("SELECT * FROM pipeline_accessions", engine_pipeline)
    assert df_pipeline.loc[0, 'id'] == 1
    assert df_pipeline.loc[0, 'experiment_accession'] == 'SRX26317792'
    assert df_pipeline.loc[0, 'sample_accession'] == 'SRS22845390'
    assert df_pipeline.loc[0, 'run_accession'] == 'SRR30914511'
    assert df_pipeline.loc[0, 'fastq_prefix'] == os.path.join(BIOLEACH_READS_DIR, 'SRR30914511')
    with source_database_engine_mysql.connect() as conn_source, engine_pipeline.connect() as conn_pipeline:
        conn_pipeline.execute(text('DROP DATABASE test_bioleach_pipeline'))
        conn_pipeline.commit()
        conn_source.execute(text('DROP DATABASE test_bioleach_source'))
        conn_source.commit()
