# -----------------------------------------------------------------------------
# Copyright (c) 2014--, The Qiita Development Team.
#
# Distributed under the terms of the BSD 3-clause License.
#
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------

from unittest import main
from os.path import isdir, exists, join, dirname
from os import remove, close
from shutil import rmtree, copyfile
from tempfile import mkdtemp, mkstemp
from json import dumps
from functools import partial

from qiita_client import ArtifactInfo
from qiita_client.testing import PluginTestCase

from qp_target_gene.split_libraries.split_libraries import (
    generate_parameters_string, generate_process_sff_commands,
    generate_split_libraries_cmd, split_libraries)


class SplitLibrariesTests(PluginTestCase):
    def setUp(self):
        self._clean_up_files = []

    def tearDown(self):
        for fp in self._clean_up_files:
            if exists(fp):
                if isdir(fp):
                    rmtree(fp)
                else:
                    remove(fp)

    def test_generate_parameters_string(self):
        parameters = {
            "min_seq_len": 200, "max_seq_len": 1000, "trim_seq_length": False,
            "min_qual_score": 25, "max_ambig": 6, "max_homopolymer": 6,
            "max_primer_mismatch": 0, "barcode_type": "golay_12",
            "max_barcode_errors": 1.5, "disable_bc_correction": False,
            "qual_score_window": 0, "disable_primers": False,
            "reverse_primers": "disable", "reverse_primer_mismatches": 0,
            "truncate_ambi_bases": False, "input_data": 1}
        obs = generate_parameters_string(parameters)
        exp = ("--min_seq_len 200 --max_seq_len 1000 --min_qual_score 25 "
               "--max_ambig 6 --max_homopolymer 6 --max_primer_mismatch 0 "
               "--barcode_type golay_12 --max_barcode_errors 1.5 "
               "--qual_score_window 0 --reverse_primer_mismatches 0 "
               "--reverse_primers disable")
        self.assertEqual(obs, exp)

    def test_generate_parameters_string_error(self):
        parameters = {
            "min_seq_len": 200, "max_seq_len": 1000, "trim_seq_length": False,
            "min_qual_score": 25, "max_ambig": 6, "max_homopolymer": 6,
            "max_primer_mismatch": 0, "barcode_type": "golay_12",
            "max_barcode_errors": 1.5, "disable_bc_correction": False,
            "qual_score_window": 0, "disable_primers": False,
            "reverse_primers": "whops", "reverse_primer_mismatches": 0,
            "truncate_ambi_bases": False, "input_data": 1}
        with self.assertRaises(ValueError):
            generate_parameters_string(parameters)

    def test_generate_process_sff_commands(self):
        out_dir = "/directory/output/"
        sff_fps = ["/directory/file1.sff", "/directory/file2.sff.gz"]
        obs_cmds, obs_seqs, obs_quals = generate_process_sff_commands(
            sff_fps, out_dir)

        exp_cmds = [
            "process_sff.py -i /directory/file1.sff -o /directory/output/",
            "process_sff.py -i /directory/file2.sff.gz -o /directory/output/"]
        exp_seqs = ["/directory/output/file1.fna",
                    "/directory/output/file2.fna"]
        exp_quals = ["/directory/output/file1.qual",
                     "/directory/output/file2.qual"]

        self.assertEqual(obs_cmds, exp_cmds)
        self.assertEqual(obs_seqs, exp_seqs)
        self.assertEqual(obs_quals, exp_quals)

    def test_generate_split_libraries_cmd_single(self):
        test_dir = mkdtemp()
        self._clean_up_files.append(test_dir)
        seqs = [join(test_dir, "seqs.fna")]
        quals = [join(test_dir, "seqs.qual")]
        mapping_file = join(test_dir, "mapping_file.txt")
        with open(mapping_file, 'w') as f:
            f.write(MAPPING_FILE_SINGLE)
        out_dir = join(test_dir, 'sl_out')
        params = {
            "min_seq_len": 200, "max_seq_len": 1000, "trim_seq_length": False,